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 6c4c5c5b 2007-03-26 devnull static Word *varmatch(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 6c4c5c5b 2007-03-26 devnull w = varmatch(b->start);
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 6c4c5c5b 2007-03-26 devnull varmatch(char *name)
61 76193d7c 2003-09-30 devnull {
62 76193d7c 2003-09-30 devnull Word *w;
63 76193d7c 2003-09-30 devnull Symtab *sym;
64 fa325e9b 2020-01-10 cross
65 76193d7c 2003-09-30 devnull sym = symlook(name, S_VAR, 0);
66 76193d7c 2003-09-30 devnull if(sym){
67 76193d7c 2003-09-30 devnull /* check for at least one non-NULL value */
68 3fe9465a 2006-04-20 devnull for (w = sym->u.ptr; w; w = w->next)
69 76193d7c 2003-09-30 devnull if(w->s && *w->s)
70 76193d7c 2003-09-30 devnull return wdup(w);
71 76193d7c 2003-09-30 devnull }
72 76193d7c 2003-09-30 devnull return 0;
73 76193d7c 2003-09-30 devnull }
74 76193d7c 2003-09-30 devnull
75 76193d7c 2003-09-30 devnull static Word*
76 76193d7c 2003-09-30 devnull expandvar(char **s)
77 76193d7c 2003-09-30 devnull {
78 76193d7c 2003-09-30 devnull Word *w;
79 76193d7c 2003-09-30 devnull Bufblock *buf;
80 76193d7c 2003-09-30 devnull Symtab *sym;
81 76193d7c 2003-09-30 devnull char *cp, *begin, *end;
82 76193d7c 2003-09-30 devnull
83 76193d7c 2003-09-30 devnull begin = *s;
84 76193d7c 2003-09-30 devnull (*s)++; /* skip the '{' */
85 76193d7c 2003-09-30 devnull buf = varname(s);
86 76193d7c 2003-09-30 devnull if (buf == 0)
87 76193d7c 2003-09-30 devnull return 0;
88 76193d7c 2003-09-30 devnull cp = *s;
89 76193d7c 2003-09-30 devnull if (*cp == '}') { /* ${name} variant*/
90 76193d7c 2003-09-30 devnull (*s)++; /* skip the '}' */
91 6c4c5c5b 2007-03-26 devnull w = varmatch(buf->start);
92 76193d7c 2003-09-30 devnull freebuf(buf);
93 76193d7c 2003-09-30 devnull return w;
94 76193d7c 2003-09-30 devnull }
95 76193d7c 2003-09-30 devnull if (*cp != ':') {
96 76193d7c 2003-09-30 devnull SYNERR(-1);
97 76193d7c 2003-09-30 devnull fprint(2, "bad variable name <%s>\n", buf->start);
98 76193d7c 2003-09-30 devnull freebuf(buf);
99 76193d7c 2003-09-30 devnull return 0;
100 76193d7c 2003-09-30 devnull }
101 76193d7c 2003-09-30 devnull cp++;
102 9aa1c92f 2005-01-04 devnull end = shellt->charin(cp , "}");
103 76193d7c 2003-09-30 devnull if(end == 0){
104 76193d7c 2003-09-30 devnull SYNERR(-1);
105 76193d7c 2003-09-30 devnull fprint(2, "missing '}': %s\n", begin);
106 76193d7c 2003-09-30 devnull Exit();
107 76193d7c 2003-09-30 devnull }
108 76193d7c 2003-09-30 devnull *end = 0;
109 76193d7c 2003-09-30 devnull *s = end+1;
110 fa325e9b 2020-01-10 cross
111 76193d7c 2003-09-30 devnull sym = symlook(buf->start, S_VAR, 0);
112 3fe9465a 2006-04-20 devnull if(sym == 0 || sym->u.ptr == 0)
113 76193d7c 2003-09-30 devnull w = newword(buf->start);
114 76193d7c 2003-09-30 devnull else
115 3fe9465a 2006-04-20 devnull w = subsub(sym->u.ptr, cp, end);
116 76193d7c 2003-09-30 devnull freebuf(buf);
117 76193d7c 2003-09-30 devnull return w;
118 76193d7c 2003-09-30 devnull }
119 76193d7c 2003-09-30 devnull
120 76193d7c 2003-09-30 devnull static Word*
121 76193d7c 2003-09-30 devnull extractpat(char *s, char **r, char *term, char *end)
122 76193d7c 2003-09-30 devnull {
123 76193d7c 2003-09-30 devnull int save;
124 76193d7c 2003-09-30 devnull char *cp;
125 76193d7c 2003-09-30 devnull Word *w;
126 76193d7c 2003-09-30 devnull
127 9aa1c92f 2005-01-04 devnull cp = shellt->charin(s, term);
128 76193d7c 2003-09-30 devnull if(cp){
129 76193d7c 2003-09-30 devnull *r = cp;
130 76193d7c 2003-09-30 devnull if(cp == s)
131 76193d7c 2003-09-30 devnull return 0;
132 76193d7c 2003-09-30 devnull save = *cp;
133 76193d7c 2003-09-30 devnull *cp = 0;
134 76193d7c 2003-09-30 devnull w = stow(s);
135 76193d7c 2003-09-30 devnull *cp = save;
136 76193d7c 2003-09-30 devnull } else {
137 76193d7c 2003-09-30 devnull *r = end;
138 76193d7c 2003-09-30 devnull w = stow(s);
139 76193d7c 2003-09-30 devnull }
140 76193d7c 2003-09-30 devnull return w;
141 76193d7c 2003-09-30 devnull }
142 76193d7c 2003-09-30 devnull
143 76193d7c 2003-09-30 devnull static Word*
144 76193d7c 2003-09-30 devnull subsub(Word *v, char *s, char *end)
145 76193d7c 2003-09-30 devnull {
146 76193d7c 2003-09-30 devnull int nmid;
147 76193d7c 2003-09-30 devnull Word *head, *tail, *w, *h;
148 76193d7c 2003-09-30 devnull Word *a, *b, *c, *d;
149 76193d7c 2003-09-30 devnull Bufblock *buf;
150 76193d7c 2003-09-30 devnull char *cp, *enda;
151 76193d7c 2003-09-30 devnull
152 76193d7c 2003-09-30 devnull a = extractpat(s, &cp, "=%&", end);
153 76193d7c 2003-09-30 devnull b = c = d = 0;
154 76193d7c 2003-09-30 devnull if(PERCENT(*cp))
155 76193d7c 2003-09-30 devnull b = extractpat(cp+1, &cp, "=", end);
156 76193d7c 2003-09-30 devnull if(*cp == '=')
157 76193d7c 2003-09-30 devnull c = extractpat(cp+1, &cp, "&%", end);
158 76193d7c 2003-09-30 devnull if(PERCENT(*cp))
159 76193d7c 2003-09-30 devnull d = stow(cp+1);
160 76193d7c 2003-09-30 devnull else if(*cp)
161 76193d7c 2003-09-30 devnull d = stow(cp);
162 76193d7c 2003-09-30 devnull
163 76193d7c 2003-09-30 devnull head = tail = 0;
164 76193d7c 2003-09-30 devnull buf = newbuf();
165 76193d7c 2003-09-30 devnull for(; v; v = v->next){
166 76193d7c 2003-09-30 devnull h = w = 0;
167 76193d7c 2003-09-30 devnull if(submatch(v->s, a, b, &nmid, &enda)){
168 76193d7c 2003-09-30 devnull /* enda points to end of A match in source;
169 76193d7c 2003-09-30 devnull * nmid = number of chars between end of A and start of B
170 76193d7c 2003-09-30 devnull */
171 76193d7c 2003-09-30 devnull if(c){
172 76193d7c 2003-09-30 devnull h = w = wdup(c);
173 76193d7c 2003-09-30 devnull while(w->next)
174 76193d7c 2003-09-30 devnull w = w->next;
175 76193d7c 2003-09-30 devnull }
176 fa325e9b 2020-01-10 cross if(PERCENT(*cp) && nmid > 0){
177 76193d7c 2003-09-30 devnull if(w){
178 76193d7c 2003-09-30 devnull bufcpy(buf, w->s, strlen(w->s));
179 76193d7c 2003-09-30 devnull bufcpy(buf, enda, nmid);
180 76193d7c 2003-09-30 devnull insert(buf, 0);
181 76193d7c 2003-09-30 devnull free(w->s);
182 76193d7c 2003-09-30 devnull w->s = strdup(buf->start);
183 76193d7c 2003-09-30 devnull } else {
184 76193d7c 2003-09-30 devnull bufcpy(buf, enda, nmid);
185 76193d7c 2003-09-30 devnull insert(buf, 0);
186 76193d7c 2003-09-30 devnull h = w = newword(buf->start);
187 76193d7c 2003-09-30 devnull }
188 76193d7c 2003-09-30 devnull buf->current = buf->start;
189 76193d7c 2003-09-30 devnull }
190 76193d7c 2003-09-30 devnull if(d && *d->s){
191 76193d7c 2003-09-30 devnull if(w){
192 76193d7c 2003-09-30 devnull
193 76193d7c 2003-09-30 devnull bufcpy(buf, w->s, strlen(w->s));
194 76193d7c 2003-09-30 devnull bufcpy(buf, d->s, strlen(d->s));
195 76193d7c 2003-09-30 devnull insert(buf, 0);
196 76193d7c 2003-09-30 devnull free(w->s);
197 76193d7c 2003-09-30 devnull w->s = strdup(buf->start);
198 76193d7c 2003-09-30 devnull w->next = wdup(d->next);
199 76193d7c 2003-09-30 devnull while(w->next)
200 76193d7c 2003-09-30 devnull w = w->next;
201 76193d7c 2003-09-30 devnull buf->current = buf->start;
202 76193d7c 2003-09-30 devnull } else
203 76193d7c 2003-09-30 devnull h = w = wdup(d);
204 76193d7c 2003-09-30 devnull }
205 76193d7c 2003-09-30 devnull }
206 76193d7c 2003-09-30 devnull if(w == 0)
207 76193d7c 2003-09-30 devnull h = w = newword(v->s);
208 fa325e9b 2020-01-10 cross
209 76193d7c 2003-09-30 devnull if(head == 0)
210 76193d7c 2003-09-30 devnull head = h;
211 76193d7c 2003-09-30 devnull else
212 76193d7c 2003-09-30 devnull tail->next = h;
213 76193d7c 2003-09-30 devnull tail = w;
214 76193d7c 2003-09-30 devnull }
215 76193d7c 2003-09-30 devnull freebuf(buf);
216 76193d7c 2003-09-30 devnull delword(a);
217 76193d7c 2003-09-30 devnull delword(b);
218 76193d7c 2003-09-30 devnull delword(c);
219 76193d7c 2003-09-30 devnull delword(d);
220 76193d7c 2003-09-30 devnull return head;
221 76193d7c 2003-09-30 devnull }
222 76193d7c 2003-09-30 devnull
223 76193d7c 2003-09-30 devnull static int
224 76193d7c 2003-09-30 devnull submatch(char *s, Word *a, Word *b, int *nmid, char **enda)
225 76193d7c 2003-09-30 devnull {
226 76193d7c 2003-09-30 devnull Word *w;
227 76193d7c 2003-09-30 devnull int n;
228 76193d7c 2003-09-30 devnull char *end;
229 76193d7c 2003-09-30 devnull
230 76193d7c 2003-09-30 devnull n = 0;
231 76193d7c 2003-09-30 devnull for(w = a; w; w = w->next){
232 76193d7c 2003-09-30 devnull n = strlen(w->s);
233 76193d7c 2003-09-30 devnull if(strncmp(s, w->s, n) == 0)
234 76193d7c 2003-09-30 devnull break;
235 76193d7c 2003-09-30 devnull }
236 76193d7c 2003-09-30 devnull if(a && w == 0) /* a == NULL matches everything*/
237 76193d7c 2003-09-30 devnull return 0;
238 76193d7c 2003-09-30 devnull
239 76193d7c 2003-09-30 devnull *enda = s+n; /* pointer to end a A part match */
240 76193d7c 2003-09-30 devnull *nmid = strlen(s)-n; /* size of remainder of source */
241 76193d7c 2003-09-30 devnull end = *enda+*nmid;
242 76193d7c 2003-09-30 devnull for(w = b; w; w = w->next){
243 76193d7c 2003-09-30 devnull n = strlen(w->s);
244 76193d7c 2003-09-30 devnull if(strcmp(w->s, end-n) == 0){
245 76193d7c 2003-09-30 devnull *nmid -= n;
246 76193d7c 2003-09-30 devnull break;
247 76193d7c 2003-09-30 devnull }
248 76193d7c 2003-09-30 devnull }
249 76193d7c 2003-09-30 devnull if(b && w == 0) /* b == NULL matches everything */
250 76193d7c 2003-09-30 devnull return 0;
251 76193d7c 2003-09-30 devnull return 1;
252 76193d7c 2003-09-30 devnull }