1 #include "mk.h" 2 3 char *termchars = "'= \t"; /*used in parse.c to isolate assignment attribute*/ 4 char *shflags = "-I"; /* rc flag to force non-interactive mode */ 5 int IWS = '\1'; /* inter-word separator in env - not used in plan 9 */ 6 7 /* 8 * This file contains functions that depend on rc's syntax. Most 9 * of the routines extract strings observing rc's escape conventions 10 */ 11 12 13 /* 14 * skip a token in single quotes. 15 */ 16 static char * 17 squote(char *cp) 18 { 19 Rune r; 20 int n; 21 22 while(*cp){ 23 n = chartorune(&r, cp); 24 if(r == '\'') { 25 n += chartorune(&r, cp+n); 26 if(r != '\'') 27 return(cp); 28 } 29 cp += n; 30 } 31 SYNERR(-1); /* should never occur */ 32 fprint(2, "missing closing '\n"); 33 return 0; 34 } 35 36 /* 37 * search a string for characters in a pattern set 38 * characters in quotes and variable generators are escaped 39 */ 40 char * 41 charin(char *cp, char *pat) 42 { 43 Rune r; 44 int n, vargen; 45 46 vargen = 0; 47 while(*cp){ 48 n = chartorune(&r, cp); 49 switch(r){ 50 case '\'': /* skip quoted string */ 51 cp = squote(cp+1); /* n must = 1 */ 52 if(!cp) 53 return 0; 54 break; 55 case '$': 56 if(*(cp+1) == '{') 57 vargen = 1; 58 break; 59 case '}': 60 if(vargen) 61 vargen = 0; 62 else if(utfrune(pat, r)) 63 return cp; 64 break; 65 default: 66 if(vargen == 0 && utfrune(pat, r)) 67 return cp; 68 break; 69 } 70 cp += n; 71 } 72 if(vargen){ 73 SYNERR(-1); 74 fprint(2, "missing closing } in pattern generator\n"); 75 } 76 return 0; 77 } 78 79 /* 80 * extract an escaped token. Possible escape chars are single-quote, 81 * double-quote,and backslash. Only the first is valid for rc. the 82 * others are just inserted into the receiving buffer. 83 */ 84 char* 85 expandquote(char *s, Rune r, Bufblock *b) 86 { 87 if (r != '\'') { 88 rinsert(b, r); 89 return s; 90 } 91 92 while(*s){ 93 s += chartorune(&r, s); 94 if(r == '\'') { 95 if(*s == '\'') 96 s++; 97 else 98 return s; 99 } 100 rinsert(b, r); 101 } 102 return 0; 103 } 104 105 /* 106 * Input an escaped token. Possible escape chars are single-quote, 107 * double-quote and backslash. Only the first is a valid escape for 108 * rc; the others are just inserted into the receiving buffer. 109 */ 110 int 111 escapetoken(Biobuf *bp, Bufblock *buf, int preserve, int esc) 112 { 113 int c, line; 114 115 if(esc != '\'') 116 return 1; 117 118 line = mkinline; 119 while((c = nextrune(bp, 0)) > 0){ 120 if(c == '\''){ 121 if(preserve) 122 rinsert(buf, c); 123 c = Bgetrune(bp); 124 if (c < 0) 125 break; 126 if(c != '\''){ 127 Bungetrune(bp); 128 return 1; 129 } 130 } 131 rinsert(buf, c); 132 } 133 SYNERR(line); fprint(2, "missing closing %c\n", esc); 134 return 0; 135 } 136 137 /* 138 * copy a single-quoted string; s points to char after opening quote 139 */ 140 static char * 141 copysingle(char *s, Bufblock *buf) 142 { 143 Rune r; 144 145 while(*s){ 146 s += chartorune(&r, s); 147 rinsert(buf, r); 148 if(r == '\'') 149 break; 150 } 151 return s; 152 } 153 /* 154 * check for quoted strings. backquotes are handled here; single quotes above. 155 * s points to char after opening quote, q. 156 */ 157 char * 158 copyq(char *s, Rune q, Bufblock *buf) 159 { 160 if(q == '\'') /* copy quoted string */ 161 return copysingle(s, buf); 162 163 if(q != '`') /* not quoted */ 164 return s; 165 166 while(*s){ /* copy backquoted string */ 167 s += chartorune(&q, s); 168 rinsert(buf, q); 169 if(q == '}') 170 break; 171 if(q == '\'') 172 s = copysingle(s, buf); /* copy quoted string */ 173 } 174 return s; 175 } 176