3 static Word *subsub(Word*, char*, char*);
4 static Word *expandvar(char**);
5 static Bufblock *varname(char**);
6 static Word *extractpat(char*, char**, char*, char*);
7 static int submatch(char*, Word*, Word*, int*, char**);
8 static Word *varmatch(char *, char**);
16 if(**s == '{') /* either ${name} or ${name: A%B==C%D}*/
23 w = varmatch(b->start, s);
29 * extract a variable name
42 n = chartorune(&r, cp);
48 if (b->current == b->start){
50 fprint(2, "missing variable name <%s>\n", *s);
60 varmatch(char *name, char **s)
66 sym = symlook(name, S_VAR, 0);
68 /* check for at least one non-NULL value */
69 for (w = (Word*)sym->value; w; w = w->next)
73 for(cp = *s; *cp == ' ' || *cp == '\t'; cp++) /* skip trailing whitespace */
85 char *cp, *begin, *end;
88 (*s)++; /* skip the '{' */
93 if (*cp == '}') { /* ${name} variant*/
94 (*s)++; /* skip the '}' */
95 w = varmatch(buf->start, s);
101 fprint(2, "bad variable name <%s>\n", buf->start);
106 end = charin(cp , "}");
109 fprint(2, "missing '}': %s\n", begin);
115 sym = symlook(buf->start, S_VAR, 0);
116 if(sym == 0 || sym->value == 0)
117 w = newword(buf->start);
119 w = subsub((Word*) sym->value, cp, end);
125 extractpat(char *s, char **r, char *term, char *end)
131 cp = charin(s, term);
148 subsub(Word *v, char *s, char *end)
151 Word *head, *tail, *w, *h;
156 a = extractpat(s, &cp, "=%&", end);
159 b = extractpat(cp+1, &cp, "=", end);
161 c = extractpat(cp+1, &cp, "&%", end);
169 for(; v; v = v->next){
171 if(submatch(v->s, a, b, &nmid, &enda)){
172 /* enda points to end of A match in source;
173 * nmid = number of chars between end of A and start of B
180 if(PERCENT(*cp) && nmid > 0){
182 bufcpy(buf, w->s, strlen(w->s));
183 bufcpy(buf, enda, nmid);
186 w->s = strdup(buf->start);
188 bufcpy(buf, enda, nmid);
190 h = w = newword(buf->start);
192 buf->current = buf->start;
197 bufcpy(buf, w->s, strlen(w->s));
198 bufcpy(buf, d->s, strlen(d->s));
201 w->s = strdup(buf->start);
202 w->next = wdup(d->next);
205 buf->current = buf->start;
211 h = w = newword(v->s);
228 submatch(char *s, Word *a, Word *b, int *nmid, char **enda)
235 for(w = a; w; w = w->next){
237 if(strncmp(s, w->s, n) == 0)
240 if(a && w == 0) /* a == NULL matches everything*/
243 *enda = s+n; /* pointer to end a A part match */
244 *nmid = strlen(s)-n; /* size of remainder of source */
246 for(w = b; w; w = w->next){
248 if(strcmp(w->s, end-n) == 0){
253 if(b && w == 0) /* b == NULL matches everything */