12 /* -------- eval.c -------- */
14 /* #include "word.h" */
19 * blank interpretation
24 _PROTOTYPE(static int expand, (char *cp, struct wdblock **wbp, int f ));
25 _PROTOTYPE(static char *blank, (int f ));
26 _PROTOTYPE(static int dollar, (int quoted ));
27 _PROTOTYPE(static int grave, (int quoted ));
28 _PROTOTYPE(void globname, (char *we, char *pp ));
29 _PROTOTYPE(static char *generate, (char *start1, char *end1, char *middle, char *end ));
30 _PROTOTYPE(static int anyspcl, (struct wdblock *wb ));
31 _PROTOTYPE(static int xstrcmp, (char *p1, char *p2 ));
32 _PROTOTYPE(void glob0, (char *a0, unsigned int a1, int a2, int (*a3)(char *, char *)));
33 _PROTOTYPE(void glob1, (char *base, char *lim ));
34 _PROTOTYPE(void glob2, (char *i, char *j ));
35 _PROTOTYPE(void glob3, (char *i, char *j, char *k ));
36 _PROTOTYPE(char *memcopy, (char *ato, char *from, int nb ));
51 if (newenv(setjmp(errpt = ev)) == 0) {
52 while (*ap && isassign(*ap))
53 expand(*ap++, &wb, f & ~DOGLOB);
55 for (wf = ap; *wf; wf++) {
57 expand(*wf, &wb, f & ~DOGLOB);
60 for (wb = addword((char *)0, wb); *ap; ap++) {
61 if (!flag['k'] || !isassign(*ap))
62 expand(*ap, &wb, f & ~DOKEY);
64 wb = addword((char *)0, wb);
69 return(gflg? (char **)NULL: wp);
73 * Make the exported environment from the exported
74 * names in the dictionary. Keyword assignments
75 * will already have been done.
81 register struct wdblock *wb;
82 register struct var *vp;
85 for (vp = vlist; vp; vp = vp->next)
86 if (vp->status & EXPORT)
87 wb = addword(vp->name, wb);
88 wb = addword((char *)0, wb);
100 if (expand(cp, &wb, f)) {
101 if (wb == NULL || wb->w_nword == 0 || (cp = wb->w_words[0]) == NULL)
112 register struct wdblock **wbp;
120 if (!anys("$`'\"", cp) &&
121 !anys(ifs->value, cp) &&
122 ((f&DOGLOB)==0 || !anys("[*?", cp))) {
123 cp = strsave(cp, areanum);
126 *wbp = addword(cp, *wbp);
129 if (newenv(setjmp(errpt = ev)) == 0) {
130 PUSHIO(aword, cp, strchar);
132 while ((cp = blank(f)) && gflg == 0) {
134 cp = strsave(cp, areanum);
135 if ((f&DOGLOB) == 0) {
138 *wbp = addword(cp, *wbp);
140 *wbp = glob(cp, *wbp);
149 * Blank interpretation and quoting
157 int scanequals, foundequals;
160 scanequals = f & DOKEY;
164 switch (c = subgetc('"', foundequals)) {
172 if (f & DOBLANK && any(c, ifs->value))
181 for (c1 = c; (c = subgetc(c1, 1)) != c1;) {
184 if (c == '\'' || !any(c, "$`\""))
194 c = subgetc('"', foundequals);
196 f & (DOBLANK && any(c, ifs->value)) ||
197 (!INSUB() && any(c, "\"'"))) {
218 * Get characters, substituting for ` and $
229 if (!INSUB() && ec != '\'') {
231 if (grave(quoted) == 0)
233 e.iop->task = XGRAVE;
236 if (c == '$' && (c = dollar(quoted)) == 0) {
245 * Prepare to generate the string returned by ${} substitution.
254 register char *s, c, *cp;
262 while ((c = readc())!=0 && letnum(c))
263 if (e.linep < elinep)
271 e.iop->task = XOTHER;
272 while ((c = subgetc('"', 0))!=0 && c!='}' && c!='\n')
273 if (e.linep < elinep)
283 if (e.linep >= elinep) {
284 err("string in ${} too long");
290 for (cp = s+1; *cp; cp++)
291 if (any(*cp, "=-+?")) {
296 if (s[1] == 0 && (*s == '*' || *s == '@')) {
298 /* currently this does not distinguish $* and $@ */
299 /* should check dollar */
301 PUSHIO(awordlist, dolv+1, dolchar);
303 } else { /* trap the nasty ${=} */
309 if ((dolp = vp->value) == null) {
313 err("cannot use ${...=...} with $n");
322 dolp = strsave(cp, areanum);
327 prs("missing value for ");
335 dolp = strsave(cp, areanum);
336 if (flag['u'] && dolp == null) {
337 prs("unset variable: ");
342 PUSHIO(aword, dolp, quoted ? qstrchar : strchar);
347 * Run the command in `...` and read its output.
357 for (cp = e.iop->argp->aword; *cp != '`'; cp++)
362 if (openpipe(pf) < 0)
364 if ((i = fork()) == -1) {
370 e.iop->argp->aword = ++cp;
372 PUSHIO(afile, remap(pf[0]), quoted? qgravechar: gravechar);
376 /* allow trapped signals */
377 for (i=0; i<=_NSIG; i++)
378 if (ourtrap[i] && signal(i, SIG_IGN) != SIG_IGN)
385 cp = strsave(e.iop->argp->aword, 0);
388 freearea(areanum); /* free old space */
390 e.iop = (e.iobase = iostack) - 1;
393 PUSHIO(aword, cp, nlchar);
404 if ((s = as) != NULL)
410 /* -------- glob.c -------- */
411 /* #include "sh.h" */
417 #define scopy(x) strsave((x), areanum)
419 #define NDENT ((BLKSIZ+sizeof(struct dirent)-1)/sizeof(struct dirent))
421 static struct wdblock *cl, *nl;
422 static char spcl[] = "[?*";
435 for (pp = cp; *pp; pp++)
438 else if (!any(*pp & ~QUOTE, spcl))
441 for (cl = addword(scopy(cp), (struct wdblock *)0); anyspcl(cl); cl = nl) {
442 nl = newword(cl->w_nword*2);
443 for(i=0; i<cl->w_nword; i++) { /* for each argument */
444 for (pp = cl->w_words[i]; *pp; pp++)
445 if (any(*pp, spcl)) {
446 globname(cl->w_words[i], pp);
450 nl = addword(scopy(cl->w_words[i]), nl);
452 for(i=0; i<cl->w_nword; i++)
453 DELETE(cl->w_words[i]);
456 for(i=0; i<cl->w_nword; i++)
457 unquote(cl->w_words[i]);
458 glob0((char *)cl->w_words, cl->w_nword, sizeof(char *), xstrcmp);
460 for (i=0; i<cl->w_nword; i++)
461 wb = addword(cl->w_words[i], wb);
466 wb = addword(unquote(cp), wb);
475 register char *np, *cp;
476 char *name, *gp, *dp;
480 char dname[NAME_MAX+1];
483 for (np = we; np != pp; pp--)
486 for (dp = cp = space((int)(pp-np)+3); np < pp;)
490 for (gp = cp = space(strlen(pp)+1); *np && *np != '/';)
499 dname[NAME_MAX] = '\0';
500 while ((de=readdir(dirp))!=NULL) {
501 /* XXX Hmmm... What this could be? (abial) */
503 if (ent[j].d_ino == 0)
506 strncpy(dname, de->d_name, NAME_MAX);
510 for(k=0; k<NAME_MAX; k++)
511 if (any(dname[k], spcl))
513 if (gmatch(dname, gp)) {
514 name = generate(we, pp, dname, np);
515 if (*np && !anys(np, spcl)) {
516 if (stat(name,&dbuf)) {
521 nl = addword(name, nl);
530 * generate a pathname as below.
531 * start..end1 / middle end
532 * the slashes come for free
535 generate(start1, end1, middle, end)
541 register char *op, *xp;
543 p = op = space((int)(end1-start1)+strlen(middle)+strlen(end)+2);
544 for (xp = start1; xp != end1;)
546 for (xp = middle; (*op++ = *xp++) != '\0';)
549 for (xp = end; (*op++ = *xp++) != '\0';)
556 register struct wdblock *wb;
562 for (i=0; i<wb->w_nword; i++)
563 if (anys(spcl, *wd++))
572 return(strcmp(*(char **)p1, *(char **)p2));
575 /* -------- word.c -------- */
576 /* #include "sh.h" */
577 /* #include "word.h" */
579 #define NSTART 16 /* default number of words to allow for initially */
585 register struct wdblock *wb;
587 wb = (struct wdblock *) space(sizeof(*wb) + nw*sizeof(char *));
596 register struct wdblock *wb;
598 register struct wdblock *wb2;
602 wb = newword(NSTART);
603 if ((nw = wb->w_nword) >= wb->w_bsize) {
604 wb2 = newword(nw * 2);
605 memcopy((char *)wb2->w_words, (char *)wb->w_words, nw*sizeof(char *));
610 wb->w_words[wb->w_nword++] = wd;
616 register struct wdblock *wb;
622 return((char **)NULL);
623 if (wb->w_nword == 0) {
625 return((char **)NULL);
627 wd = (char **) space(nb = sizeof(*wd) * wb->w_nword);
628 memcopy((char *)wd, (char *)wb->w_words, nb);
629 DELETE(wb); /* perhaps should done by caller */
633 _PROTOTYPE(int (*func), (char *, char *));
637 glob0(a0, a1, a2, a3)
641 _PROTOTYPE(int (*a3), (char *, char *));
645 glob1(a0, a0 + a1 * a2);
652 register char *i, *j;
662 if ((n=(int)(lim-base)) <= v2)
664 n = v2 * (n / (2*v2));
665 hptr = lptr = base+n;
670 if ((c = (*func)(i, lptr)) == 0) {
671 glob2(i, lptr -= v2);
682 if ((c = (*func)(hptr, j)) == 0) {
683 glob2(hptr += v2, j);
688 glob3(i, hptr += v2, j);
703 if (lptr-base >= lim-hptr) {
714 glob3(j, lptr -= v2, i);
723 register char *index1, *index2, c;
740 register char *index1, *index2, *index3;
757 memcopy(ato, from, nb)
758 register char *ato, *from;