11 /* -------- eval.c -------- */
13 /* #include "word.h" */
18 * blank interpretation
23 _PROTOTYPE(static int expand
, (char *cp
, struct wdblock
**wbp
, int f
));
24 _PROTOTYPE(static char *blank
, (int f
));
25 _PROTOTYPE(static int dollar
, (int quoted
));
26 _PROTOTYPE(static int grave
, (int quoted
));
27 _PROTOTYPE(void globname
, (char *we
, char *pp
));
28 _PROTOTYPE(static char *generate
, (char *start1
, char *end1
, char *middle
, char *end
));
29 _PROTOTYPE(static int anyspcl
, (struct wdblock
*wb
));
30 _PROTOTYPE(static int xstrcmp
, (char *p1
, char *p2
));
31 _PROTOTYPE(void glob0
, (char *a0
, unsigned int a1
, int a2
, int (*a3
)(char *, char *)));
32 _PROTOTYPE(void glob1
, (char *base
, char *lim
));
33 _PROTOTYPE(void glob2
, (char *i
, char *j
));
34 _PROTOTYPE(void glob3
, (char *i
, char *j
, char *k
));
35 _PROTOTYPE(char *memcopy
, (char *ato
, char *from
, int nb
));
50 if (newenv(setjmp(errpt
= ev
)) == 0) {
51 while (*ap
&& isassign(*ap
))
52 expand(*ap
++, &wb
, f
& ~DOGLOB
);
54 for (wf
= ap
; *wf
; wf
++) {
56 expand(*wf
, &wb
, f
& ~DOGLOB
);
59 for (wb
= addword((char *)0, wb
); *ap
; ap
++) {
60 if (!flag
['k'] || !isassign(*ap
))
61 expand(*ap
, &wb
, f
& ~DOKEY
);
63 wb
= addword((char *)0, wb
);
68 return(gflg
? (char **)NULL
: wp
);
72 * Make the exported environment from the exported
73 * names in the dictionary. Keyword assignments
74 * will already have been done.
80 register struct wdblock
*wb
;
81 register struct var
*vp
;
84 for (vp
= vlist
; vp
; vp
= vp
->next
)
85 if (vp
->status
& EXPORT
)
86 wb
= addword(vp
->name
, wb
);
87 wb
= addword((char *)0, wb
);
99 if (expand(cp
, &wb
, f
)) {
100 if (wb
== NULL
|| wb
->w_nword
== 0 || (cp
= wb
->w_words
[0]) == NULL
)
111 register struct wdblock
**wbp
;
119 if (!anys("$`'\"", cp
) &&
120 !anys(ifs
->value
, cp
) &&
121 ((f
&DOGLOB
)==0 || !anys("[*?", cp
))) {
122 cp
= strsave(cp
, areanum
);
125 *wbp
= addword(cp
, *wbp
);
128 if (newenv(setjmp(errpt
= ev
)) == 0) {
129 PUSHIO(aword
, cp
, strchar
);
131 while ((cp
= blank(f
)) && gflg
== 0) {
133 cp
= strsave(cp
, areanum
);
134 if ((f
&DOGLOB
) == 0) {
137 *wbp
= addword(cp
, *wbp
);
139 *wbp
= glob(cp
, *wbp
);
148 * Blank interpretation and quoting
156 int scanequals
, foundequals
;
159 scanequals
= f
& DOKEY
;
163 switch (c
= subgetc('"', foundequals
)) {
171 if (f
& DOBLANK
&& any(c
, ifs
->value
))
180 for (c1
= c
; (c
= subgetc(c1
, 1)) != c1
;) {
183 if (c
== '\'' || !any(c
, "$`\""))
193 c
= subgetc('"', foundequals
);
195 (f
& DOBLANK
&& any(c
, ifs
->value
)) ||
196 (!INSUB() && any(c
, "\"'"))) {
217 * Get characters, substituting for ` and $
228 if (!INSUB() && ec
!= '\'') {
230 if (grave(quoted
) == 0)
232 e
.iop
->task
= XGRAVE
;
235 if (c
== '$' && (c
= dollar(quoted
)) == 0) {
244 * Prepare to generate the string returned by ${} substitution.
253 register char *s
, c
, *cp
;
261 while ((c
= readc())!=0 && letnum(c
))
262 if (e
.linep
< elinep
)
270 e
.iop
->task
= XOTHER
;
271 while ((c
= subgetc('"', 0))!=0 && c
!='}' && c
!='\n')
272 if (e
.linep
< elinep
)
282 if (e
.linep
>= elinep
) {
283 err("string in ${} too long");
289 for (cp
= s
+1; *cp
; cp
++)
290 if (any(*cp
, "=-+?")) {
295 if (s
[1] == 0 && (*s
== '*' || *s
== '@')) {
297 /* currently this does not distinguish $* and $@ */
298 /* should check dollar */
300 PUSHIO(awordlist
, dolv
+1, dolchar
);
302 } else { /* trap the nasty ${=} */
309 if ((dolp
= vp
->value
) == null
) {
313 err("cannot use ${...=...} with $n");
317 cp
= evalstr(strsave(cp
, areanum
),DOSUB
);
323 dolp
= evalstr(strsave(cp
, areanum
),DOSUB
);
328 prs("missing value for ");
331 err(evalstr(strsave(cp
, areanum
),DOSUB
));
335 } else if (c
== '+') {
336 dolp
= evalstr(strsave(cp
, areanum
),DOSUB
);
338 if (flag
['u'] && dolp
== null
) {
339 prs("unset variable: ");
343 PUSHIO(aword
, dolp
, quoted
? qstrchar
: strchar
);
348 * Run the command in `...` and read its output.
356 register char *cp
,*s
;
365 e
.iop
->task
= XOTHER
;
366 while ((c
= subgetc('\'', 0))!=0 && c
!='`')
367 if (e
.linep
< elinep
)
375 if (openpipe(pf
) < 0)
377 if ((i
= fork()) == -1) {
385 PUSHIO(afile
, remap(pf
[0]), quoted
? qgravechar
: gravechar
);
389 /* allow trapped signals */
390 for (i
=0; i
<_NSIG
; i
++)
391 if (ourtrap
[i
] && signal(i
, SIG_IGN
) != SIG_IGN
)
398 cp
= strsave(e
.linep
= s
, 0);
401 freearea(areanum
); /* free old space */
403 e
.iop
= (e
.iobase
= iostack
) - 1;
406 PUSHIO(aword
, cp
, nlchar
);
417 if ((s
= as
) != NULL
)
423 /* -------- glob.c -------- */
424 /* #include "sh.h" */
430 #define scopy(x) strsave((x), areanum)
432 #define NDENT ((BLKSIZ+sizeof(struct direct)-1)/sizeof(struct direct))
434 static struct wdblock
*cl
, *nl
;
435 static char spcl
[] = "[?*";
448 for (pp
= cp
; *pp
; pp
++)
451 else if (!any(*pp
& ~QUOTE
, spcl
))
454 for (cl
= addword(scopy(cp
), (struct wdblock
*)0); anyspcl(cl
); cl
= nl
) {
455 nl
= newword(cl
->w_nword
*2);
456 for(i
=0; i
<cl
->w_nword
; i
++) { /* for each argument */
457 for (pp
= cl
->w_words
[i
]; *pp
; pp
++)
458 if (any(*pp
, spcl
)) {
459 globname(cl
->w_words
[i
], pp
);
463 nl
= addword(scopy(cl
->w_words
[i
]), nl
);
465 for(i
=0; i
<cl
->w_nword
; i
++)
466 DELETE(cl
->w_words
[i
]);
469 for(i
=0; i
<cl
->w_nword
; i
++)
470 unquote(cl
->w_words
[i
]);
471 glob0((char *)cl
->w_words
, cl
->w_nword
, sizeof(char *), xstrcmp
);
473 for (i
=0; i
<cl
->w_nword
; i
++)
474 wb
= addword(cl
->w_words
[i
], wb
);
479 wb
= addword(unquote(cp
), wb
);
488 register char *np
, *cp
;
489 char *name
, *gp
, *dp
;
491 struct direct ent
[NDENT
];
492 char dname
[NAME_MAX
+1];
495 for (np
= we
; np
!= pp
; pp
--)
498 for (dp
= cp
= space((int)(pp
-np
)+3); np
< pp
;)
502 for (gp
= cp
= space(strlen(pp
)+1); *np
&& *np
!= '/';)
511 dname
[NAME_MAX
] = '\0';
512 while ((n
= read(dn
, (char *)ent
, sizeof(ent
))) >= sizeof(*ent
)) {
514 for (j
=0; j
<n
; j
++) {
515 if (ent
[j
].d_ino
== 0)
517 strncpy(dname
, ent
[j
].d_name
, NAME_MAX
);
521 for(k
=0; k
<NAME_MAX
; k
++)
522 if (any(dname
[k
], spcl
))
524 if (gmatch(dname
, gp
)) {
525 name
= generate(we
, pp
, dname
, np
);
526 if (*np
&& !anys(np
, spcl
)) {
527 if (stat(name
,&dbuf
)) {
532 nl
= addword(name
, nl
);
542 * generate a pathname as below.
543 * start..end1 / middle end
544 * the slashes come for free
547 generate(start1
, end1
, middle
, end
)
553 register char *op
, *xp
;
555 p
= op
= space((int)(end1
-start1
)+strlen(middle
)+strlen(end
)+2);
556 for (xp
= start1
; xp
!= end1
;)
558 for (xp
= middle
; (*op
++ = *xp
++) != '\0';)
561 for (xp
= end
; (*op
++ = *xp
++) != '\0';)
568 register struct wdblock
*wb
;
574 for (i
=0; i
<wb
->w_nword
; i
++)
575 if (anys(spcl
, *wd
++))
584 return(strcmp(*(char **)p1
, *(char **)p2
));
587 /* -------- word.c -------- */
588 /* #include "sh.h" */
589 /* #include "word.h" */
591 #define NSTART 16 /* default number of words to allow for initially */
597 register struct wdblock
*wb
;
599 wb
= (struct wdblock
*) space(sizeof(*wb
) + nw
*sizeof(char *));
608 register struct wdblock
*wb
;
610 register struct wdblock
*wb2
;
614 wb
= newword(NSTART
);
615 if ((nw
= wb
->w_nword
) >= wb
->w_bsize
) {
616 wb2
= newword(nw
* 2);
617 memcopy((char *)wb2
->w_words
, (char *)wb
->w_words
, nw
*sizeof(char *));
622 wb
->w_words
[wb
->w_nword
++] = wd
;
628 register struct wdblock
*wb
;
634 return((char **)NULL
);
635 if (wb
->w_nword
== 0) {
637 return((char **)NULL
);
639 wd
= (char **) space(nb
= sizeof(*wd
) * wb
->w_nword
);
640 memcopy((char *)wd
, (char *)wb
->w_words
, nb
);
641 DELETE(wb
); /* perhaps should done by caller */
645 _PROTOTYPE(int (*func
), (char *, char *));
649 glob0(a0
, a1
, a2
, a3
)
653 _PROTOTYPE(int (*a3
), (char *, char *));
657 glob1(a0
, a0
+ a1
* a2
);
664 register char *i
, *j
;
674 if ((n
=(int)(lim
-base
)) <= v2
)
676 n
= v2
* (n
/ (2*v2
));
677 hptr
= lptr
= base
+n
;
682 if ((c
= (*func
)(i
, lptr
)) == 0) {
683 glob2(i
, lptr
-= v2
);
694 if ((c
= (*func
)(hptr
, j
)) == 0) {
695 glob2(hptr
+= v2
, j
);
700 glob3(i
, hptr
+= v2
, j
);
715 if (lptr
-base
>= lim
-hptr
) {
726 glob3(j
, lptr
-= v2
, i
);
735 register char *index1
, *index2
, c
;
752 register char *index1
, *index2
, *index3
;
769 memcopy(ato
, from
, nb
)
770 register char *ato
, *from
;