Blob


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