Blame


1 76193d7c 2003-09-30 devnull #include "mk.h"
2 76193d7c 2003-09-30 devnull
3 76193d7c 2003-09-30 devnull static Word *subsub(Word*, char*, char*);
4 76193d7c 2003-09-30 devnull static Word *expandvar(char**);
5 76193d7c 2003-09-30 devnull static Bufblock *varname(char**);
6 76193d7c 2003-09-30 devnull static Word *extractpat(char*, char**, char*, char*);
7 76193d7c 2003-09-30 devnull static int submatch(char*, Word*, Word*, int*, char**);
8 76193d7c 2003-09-30 devnull static Word *varmatch(char *, char**);
9 76193d7c 2003-09-30 devnull
10 76193d7c 2003-09-30 devnull Word *
11 76193d7c 2003-09-30 devnull varsub(char **s)
12 76193d7c 2003-09-30 devnull {
13 76193d7c 2003-09-30 devnull Bufblock *b;
14 76193d7c 2003-09-30 devnull Word *w;
15 76193d7c 2003-09-30 devnull
16 76193d7c 2003-09-30 devnull if(**s == '{') /* either ${name} or ${name: A%B==C%D}*/
17 76193d7c 2003-09-30 devnull return expandvar(s);
18 76193d7c 2003-09-30 devnull
19 76193d7c 2003-09-30 devnull b = varname(s);
20 76193d7c 2003-09-30 devnull if(b == 0)
21 76193d7c 2003-09-30 devnull return 0;
22 76193d7c 2003-09-30 devnull
23 76193d7c 2003-09-30 devnull w = varmatch(b->start, s);
24 76193d7c 2003-09-30 devnull freebuf(b);
25 76193d7c 2003-09-30 devnull return w;
26 76193d7c 2003-09-30 devnull }
27 76193d7c 2003-09-30 devnull
28 76193d7c 2003-09-30 devnull /*
29 76193d7c 2003-09-30 devnull * extract a variable name
30 76193d7c 2003-09-30 devnull */
31 76193d7c 2003-09-30 devnull static Bufblock*
32 76193d7c 2003-09-30 devnull varname(char **s)
33 76193d7c 2003-09-30 devnull {
34 76193d7c 2003-09-30 devnull Bufblock *b;
35 76193d7c 2003-09-30 devnull char *cp;
36 76193d7c 2003-09-30 devnull Rune r;
37 76193d7c 2003-09-30 devnull int n;
38 76193d7c 2003-09-30 devnull
39 76193d7c 2003-09-30 devnull b = newbuf();
40 76193d7c 2003-09-30 devnull cp = *s;
41 76193d7c 2003-09-30 devnull for(;;){
42 76193d7c 2003-09-30 devnull n = chartorune(&r, cp);
43 76193d7c 2003-09-30 devnull if (!WORDCHR(r))
44 76193d7c 2003-09-30 devnull break;
45 76193d7c 2003-09-30 devnull rinsert(b, r);
46 76193d7c 2003-09-30 devnull cp += n;
47 76193d7c 2003-09-30 devnull }
48 76193d7c 2003-09-30 devnull if (b->current == b->start){
49 76193d7c 2003-09-30 devnull SYNERR(-1);
50 76193d7c 2003-09-30 devnull fprint(2, "missing variable name <%s>\n", *s);
51 76193d7c 2003-09-30 devnull freebuf(b);
52 76193d7c 2003-09-30 devnull return 0;
53 76193d7c 2003-09-30 devnull }
54 76193d7c 2003-09-30 devnull *s = cp;
55 76193d7c 2003-09-30 devnull insert(b, 0);
56 76193d7c 2003-09-30 devnull return b;
57 76193d7c 2003-09-30 devnull }
58 76193d7c 2003-09-30 devnull
59 76193d7c 2003-09-30 devnull static Word*
60 76193d7c 2003-09-30 devnull varmatch(char *name, char **s)
61 76193d7c 2003-09-30 devnull {
62 76193d7c 2003-09-30 devnull Word *w;
63 76193d7c 2003-09-30 devnull Symtab *sym;
64 76193d7c 2003-09-30 devnull char *cp;
65 76193d7c 2003-09-30 devnull
66 76193d7c 2003-09-30 devnull sym = symlook(name, S_VAR, 0);
67 76193d7c 2003-09-30 devnull if(sym){
68 76193d7c 2003-09-30 devnull /* check for at least one non-NULL value */
69 76193d7c 2003-09-30 devnull for (w = (Word*)sym->value; w; w = w->next)
70 76193d7c 2003-09-30 devnull if(w->s && *w->s)
71 76193d7c 2003-09-30 devnull return wdup(w);
72 76193d7c 2003-09-30 devnull }
73 76193d7c 2003-09-30 devnull for(cp = *s; *cp == ' ' || *cp == '\t'; cp++) /* skip trailing whitespace */
74 76193d7c 2003-09-30 devnull ;
75 76193d7c 2003-09-30 devnull *s = cp;
76 76193d7c 2003-09-30 devnull return 0;
77 76193d7c 2003-09-30 devnull }
78 76193d7c 2003-09-30 devnull
79 76193d7c 2003-09-30 devnull static Word*
80 76193d7c 2003-09-30 devnull expandvar(char **s)
81 76193d7c 2003-09-30 devnull {
82 76193d7c 2003-09-30 devnull Word *w;
83 76193d7c 2003-09-30 devnull Bufblock *buf;
84 76193d7c 2003-09-30 devnull Symtab *sym;
85 76193d7c 2003-09-30 devnull char *cp, *begin, *end;
86 76193d7c 2003-09-30 devnull
87 76193d7c 2003-09-30 devnull begin = *s;
88 76193d7c 2003-09-30 devnull (*s)++; /* skip the '{' */
89 76193d7c 2003-09-30 devnull buf = varname(s);
90 76193d7c 2003-09-30 devnull if (buf == 0)
91 76193d7c 2003-09-30 devnull return 0;
92 76193d7c 2003-09-30 devnull cp = *s;
93 76193d7c 2003-09-30 devnull if (*cp == '}') { /* ${name} variant*/
94 76193d7c 2003-09-30 devnull (*s)++; /* skip the '}' */
95 76193d7c 2003-09-30 devnull w = varmatch(buf->start, s);
96 76193d7c 2003-09-30 devnull freebuf(buf);
97 76193d7c 2003-09-30 devnull return w;
98 76193d7c 2003-09-30 devnull }
99 76193d7c 2003-09-30 devnull if (*cp != ':') {
100 76193d7c 2003-09-30 devnull SYNERR(-1);
101 76193d7c 2003-09-30 devnull fprint(2, "bad variable name <%s>\n", buf->start);
102 76193d7c 2003-09-30 devnull freebuf(buf);
103 76193d7c 2003-09-30 devnull return 0;
104 76193d7c 2003-09-30 devnull }
105 76193d7c 2003-09-30 devnull cp++;
106 9aa1c92f 2005-01-04 devnull end = shellt->charin(cp , "}");
107 76193d7c 2003-09-30 devnull if(end == 0){
108 76193d7c 2003-09-30 devnull SYNERR(-1);
109 76193d7c 2003-09-30 devnull fprint(2, "missing '}': %s\n", begin);
110 76193d7c 2003-09-30 devnull Exit();
111 76193d7c 2003-09-30 devnull }
112 76193d7c 2003-09-30 devnull *end = 0;
113 76193d7c 2003-09-30 devnull *s = end+1;
114 76193d7c 2003-09-30 devnull
115 76193d7c 2003-09-30 devnull sym = symlook(buf->start, S_VAR, 0);
116 76193d7c 2003-09-30 devnull if(sym == 0 || sym->value == 0)
117 76193d7c 2003-09-30 devnull w = newword(buf->start);
118 76193d7c 2003-09-30 devnull else
119 76193d7c 2003-09-30 devnull w = subsub((Word*) sym->value, cp, end);
120 76193d7c 2003-09-30 devnull freebuf(buf);
121 76193d7c 2003-09-30 devnull return w;
122 76193d7c 2003-09-30 devnull }
123 76193d7c 2003-09-30 devnull
124 76193d7c 2003-09-30 devnull static Word*
125 76193d7c 2003-09-30 devnull extractpat(char *s, char **r, char *term, char *end)
126 76193d7c 2003-09-30 devnull {
127 76193d7c 2003-09-30 devnull int save;
128 76193d7c 2003-09-30 devnull char *cp;
129 76193d7c 2003-09-30 devnull Word *w;
130 76193d7c 2003-09-30 devnull
131 9aa1c92f 2005-01-04 devnull cp = shellt->charin(s, term);
132 76193d7c 2003-09-30 devnull if(cp){
133 76193d7c 2003-09-30 devnull *r = cp;
134 76193d7c 2003-09-30 devnull if(cp == s)
135 76193d7c 2003-09-30 devnull return 0;
136 76193d7c 2003-09-30 devnull save = *cp;
137 76193d7c 2003-09-30 devnull *cp = 0;
138 76193d7c 2003-09-30 devnull w = stow(s);
139 76193d7c 2003-09-30 devnull *cp = save;
140 76193d7c 2003-09-30 devnull } else {
141 76193d7c 2003-09-30 devnull *r = end;
142 76193d7c 2003-09-30 devnull w = stow(s);
143 76193d7c 2003-09-30 devnull }
144 76193d7c 2003-09-30 devnull return w;
145 76193d7c 2003-09-30 devnull }
146 76193d7c 2003-09-30 devnull
147 76193d7c 2003-09-30 devnull static Word*
148 76193d7c 2003-09-30 devnull subsub(Word *v, char *s, char *end)
149 76193d7c 2003-09-30 devnull {
150 76193d7c 2003-09-30 devnull int nmid;
151 76193d7c 2003-09-30 devnull Word *head, *tail, *w, *h;
152 76193d7c 2003-09-30 devnull Word *a, *b, *c, *d;
153 76193d7c 2003-09-30 devnull Bufblock *buf;
154 76193d7c 2003-09-30 devnull char *cp, *enda;
155 76193d7c 2003-09-30 devnull
156 76193d7c 2003-09-30 devnull a = extractpat(s, &cp, "=%&", end);
157 76193d7c 2003-09-30 devnull b = c = d = 0;
158 76193d7c 2003-09-30 devnull if(PERCENT(*cp))
159 76193d7c 2003-09-30 devnull b = extractpat(cp+1, &cp, "=", end);
160 76193d7c 2003-09-30 devnull if(*cp == '=')
161 76193d7c 2003-09-30 devnull c = extractpat(cp+1, &cp, "&%", end);
162 76193d7c 2003-09-30 devnull if(PERCENT(*cp))
163 76193d7c 2003-09-30 devnull d = stow(cp+1);
164 76193d7c 2003-09-30 devnull else if(*cp)
165 76193d7c 2003-09-30 devnull d = stow(cp);
166 76193d7c 2003-09-30 devnull
167 76193d7c 2003-09-30 devnull head = tail = 0;
168 76193d7c 2003-09-30 devnull buf = newbuf();
169 76193d7c 2003-09-30 devnull for(; v; v = v->next){
170 76193d7c 2003-09-30 devnull h = w = 0;
171 76193d7c 2003-09-30 devnull if(submatch(v->s, a, b, &nmid, &enda)){
172 76193d7c 2003-09-30 devnull /* enda points to end of A match in source;
173 76193d7c 2003-09-30 devnull * nmid = number of chars between end of A and start of B
174 76193d7c 2003-09-30 devnull */
175 76193d7c 2003-09-30 devnull if(c){
176 76193d7c 2003-09-30 devnull h = w = wdup(c);
177 76193d7c 2003-09-30 devnull while(w->next)
178 76193d7c 2003-09-30 devnull w = w->next;
179 76193d7c 2003-09-30 devnull }
180 76193d7c 2003-09-30 devnull if(PERCENT(*cp) && nmid > 0){
181 76193d7c 2003-09-30 devnull if(w){
182 76193d7c 2003-09-30 devnull bufcpy(buf, w->s, strlen(w->s));
183 76193d7c 2003-09-30 devnull bufcpy(buf, enda, nmid);
184 76193d7c 2003-09-30 devnull insert(buf, 0);
185 76193d7c 2003-09-30 devnull free(w->s);
186 76193d7c 2003-09-30 devnull w->s = strdup(buf->start);
187 76193d7c 2003-09-30 devnull } else {
188 76193d7c 2003-09-30 devnull bufcpy(buf, enda, nmid);
189 76193d7c 2003-09-30 devnull insert(buf, 0);
190 76193d7c 2003-09-30 devnull h = w = newword(buf->start);
191 76193d7c 2003-09-30 devnull }
192 76193d7c 2003-09-30 devnull buf->current = buf->start;
193 76193d7c 2003-09-30 devnull }
194 76193d7c 2003-09-30 devnull if(d && *d->s){
195 76193d7c 2003-09-30 devnull if(w){
196 76193d7c 2003-09-30 devnull
197 76193d7c 2003-09-30 devnull bufcpy(buf, w->s, strlen(w->s));
198 76193d7c 2003-09-30 devnull bufcpy(buf, d->s, strlen(d->s));
199 76193d7c 2003-09-30 devnull insert(buf, 0);
200 76193d7c 2003-09-30 devnull free(w->s);
201 76193d7c 2003-09-30 devnull w->s = strdup(buf->start);
202 76193d7c 2003-09-30 devnull w->next = wdup(d->next);
203 76193d7c 2003-09-30 devnull while(w->next)
204 76193d7c 2003-09-30 devnull w = w->next;
205 76193d7c 2003-09-30 devnull buf->current = buf->start;
206 76193d7c 2003-09-30 devnull } else
207 76193d7c 2003-09-30 devnull h = w = wdup(d);
208 76193d7c 2003-09-30 devnull }
209 76193d7c 2003-09-30 devnull }
210 76193d7c 2003-09-30 devnull if(w == 0)
211 76193d7c 2003-09-30 devnull h = w = newword(v->s);
212 76193d7c 2003-09-30 devnull
213 76193d7c 2003-09-30 devnull if(head == 0)
214 76193d7c 2003-09-30 devnull head = h;
215 76193d7c 2003-09-30 devnull else
216 76193d7c 2003-09-30 devnull tail->next = h;
217 76193d7c 2003-09-30 devnull tail = w;
218 76193d7c 2003-09-30 devnull }
219 76193d7c 2003-09-30 devnull freebuf(buf);
220 76193d7c 2003-09-30 devnull delword(a);
221 76193d7c 2003-09-30 devnull delword(b);
222 76193d7c 2003-09-30 devnull delword(c);
223 76193d7c 2003-09-30 devnull delword(d);
224 76193d7c 2003-09-30 devnull return head;
225 76193d7c 2003-09-30 devnull }
226 76193d7c 2003-09-30 devnull
227 76193d7c 2003-09-30 devnull static int
228 76193d7c 2003-09-30 devnull submatch(char *s, Word *a, Word *b, int *nmid, char **enda)
229 76193d7c 2003-09-30 devnull {
230 76193d7c 2003-09-30 devnull Word *w;
231 76193d7c 2003-09-30 devnull int n;
232 76193d7c 2003-09-30 devnull char *end;
233 76193d7c 2003-09-30 devnull
234 76193d7c 2003-09-30 devnull n = 0;
235 76193d7c 2003-09-30 devnull for(w = a; w; w = w->next){
236 76193d7c 2003-09-30 devnull n = strlen(w->s);
237 76193d7c 2003-09-30 devnull if(strncmp(s, w->s, n) == 0)
238 76193d7c 2003-09-30 devnull break;
239 76193d7c 2003-09-30 devnull }
240 76193d7c 2003-09-30 devnull if(a && w == 0) /* a == NULL matches everything*/
241 76193d7c 2003-09-30 devnull return 0;
242 76193d7c 2003-09-30 devnull
243 76193d7c 2003-09-30 devnull *enda = s+n; /* pointer to end a A part match */
244 76193d7c 2003-09-30 devnull *nmid = strlen(s)-n; /* size of remainder of source */
245 76193d7c 2003-09-30 devnull end = *enda+*nmid;
246 76193d7c 2003-09-30 devnull for(w = b; w; w = w->next){
247 76193d7c 2003-09-30 devnull n = strlen(w->s);
248 76193d7c 2003-09-30 devnull if(strcmp(w->s, end-n) == 0){
249 76193d7c 2003-09-30 devnull *nmid -= n;
250 76193d7c 2003-09-30 devnull break;
251 76193d7c 2003-09-30 devnull }
252 76193d7c 2003-09-30 devnull }
253 76193d7c 2003-09-30 devnull if(b && w == 0) /* b == NULL matches everything */
254 76193d7c 2003-09-30 devnull return 0;
255 76193d7c 2003-09-30 devnull return 1;
256 76193d7c 2003-09-30 devnull }