pci: don't do sanity check for missing pci bus, the check can misfire.
[minix.git] / commands / sh / sh4.c
blob4fe04df7341658c77bfdfd44488d5a6a45b0e3c9
1 #define Extern extern
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <sys/dir.h>
5 #include <limits.h>
6 #include <signal.h>
7 #include <errno.h>
8 #include <setjmp.h>
9 #include "sh.h"
11 /* -------- eval.c -------- */
12 /* #include "sh.h" */
13 /* #include "word.h" */
16 * ${}
17 * `command`
18 * blank interpretation
19 * quoting
20 * glob
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 ));
37 char **
38 eval(ap, f)
39 register char **ap;
40 int f;
42 struct wdblock *wb;
43 char **wp;
44 char **wf;
45 jmp_buf ev;
47 wp = NULL;
48 wb = NULL;
49 wf = NULL;
50 if (newenv(setjmp(errpt = ev)) == 0) {
51 while (*ap && isassign(*ap))
52 expand(*ap++, &wb, f & ~DOGLOB);
53 if (flag['k']) {
54 for (wf = ap; *wf; wf++) {
55 if (isassign(*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);
64 wp = getwords(wb);
65 quitenv();
66 } else
67 gflg = 1;
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.
76 char **
77 makenv()
80 register struct wdblock *wb;
81 register struct var *vp;
83 wb = NULL;
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);
88 return(getwords(wb));
91 char *
92 evalstr(cp, f)
93 register char *cp;
94 int f;
96 struct wdblock *wb;
98 wb = NULL;
99 if (expand(cp, &wb, f)) {
100 if (wb == NULL || wb->w_nword == 0 || (cp = wb->w_words[0]) == NULL)
101 cp = "";
102 DELETE(wb);
103 } else
104 cp = NULL;
105 return(cp);
108 static int
109 expand(cp, wbp, f)
110 register char *cp;
111 register struct wdblock **wbp;
112 int f;
114 jmp_buf ev;
116 gflg = 0;
117 if (cp == NULL)
118 return(0);
119 if (!anys("$`'\"", cp) &&
120 !anys(ifs->value, cp) &&
121 ((f&DOGLOB)==0 || !anys("[*?", cp))) {
122 cp = strsave(cp, areanum);
123 if (f & DOTRIM)
124 unquote(cp);
125 *wbp = addword(cp, *wbp);
126 return(1);
128 if (newenv(setjmp(errpt = ev)) == 0) {
129 PUSHIO(aword, cp, strchar);
130 e.iobase = e.iop;
131 while ((cp = blank(f)) && gflg == 0) {
132 e.linep = cp;
133 cp = strsave(cp, areanum);
134 if ((f&DOGLOB) == 0) {
135 if (f & DOTRIM)
136 unquote(cp);
137 *wbp = addword(cp, *wbp);
138 } else
139 *wbp = glob(cp, *wbp);
141 quitenv();
142 } else
143 gflg = 1;
144 return(gflg == 0);
148 * Blank interpretation and quoting
150 static char *
151 blank(f)
152 int f;
154 register c, c1;
155 register char *sp;
156 int scanequals, foundequals;
158 sp = e.linep;
159 scanequals = f & DOKEY;
160 foundequals = 0;
162 loop:
163 switch (c = subgetc('"', foundequals)) {
164 case 0:
165 if (sp == e.linep)
166 return(0);
167 *e.linep++ = 0;
168 return(sp);
170 default:
171 if (f & DOBLANK && any(c, ifs->value))
172 goto loop;
173 break;
175 case '"':
176 case '\'':
177 scanequals = 0;
178 if (INSUB())
179 break;
180 for (c1 = c; (c = subgetc(c1, 1)) != c1;) {
181 if (c == 0)
182 break;
183 if (c == '\'' || !any(c, "$`\""))
184 c |= QUOTE;
185 *e.linep++ = c;
187 c = 0;
189 unget(c);
190 if (!letter(c))
191 scanequals = 0;
192 for (;;) {
193 c = subgetc('"', foundequals);
194 if (c == 0 ||
195 (f & DOBLANK && any(c, ifs->value)) ||
196 (!INSUB() && any(c, "\"'"))) {
197 scanequals = 0;
198 unget(c);
199 if (any(c, "\"'"))
200 goto loop;
201 break;
203 if (scanequals)
204 if (c == '=') {
205 foundequals = 1;
206 scanequals = 0;
208 else if (!letnum(c))
209 scanequals = 0;
210 *e.linep++ = c;
212 *e.linep++ = 0;
213 return(sp);
217 * Get characters, substituting for ` and $
220 subgetc(ec, quoted)
221 register char ec;
222 int quoted;
224 register char c;
226 again:
227 c = getc(ec);
228 if (!INSUB() && ec != '\'') {
229 if (c == '`') {
230 if (grave(quoted) == 0)
231 return(0);
232 e.iop->task = XGRAVE;
233 goto again;
235 if (c == '$' && (c = dollar(quoted)) == 0) {
236 e.iop->task = XDOLL;
237 goto again;
240 return(c);
244 * Prepare to generate the string returned by ${} substitution.
246 static int
247 dollar(quoted)
248 int quoted;
250 int otask;
251 struct io *oiop;
252 char *dolp;
253 register char *s, c, *cp;
254 struct var *vp;
256 c = readc();
257 s = e.linep;
258 if (c != '{') {
259 *e.linep++ = c;
260 if (letter(c)) {
261 while ((c = readc())!=0 && letnum(c))
262 if (e.linep < elinep)
263 *e.linep++ = c;
264 unget(c);
266 c = 0;
267 } else {
268 oiop = e.iop;
269 otask = e.iop->task;
270 e.iop->task = XOTHER;
271 while ((c = subgetc('"', 0))!=0 && c!='}' && c!='\n')
272 if (e.linep < elinep)
273 *e.linep++ = c;
274 if (oiop == e.iop)
275 e.iop->task = otask;
276 if (c != '}') {
277 err("unclosed ${");
278 gflg++;
279 return(c);
282 if (e.linep >= elinep) {
283 err("string in ${} too long");
284 gflg++;
285 e.linep -= 10;
287 *e.linep = 0;
288 if (*s)
289 for (cp = s+1; *cp; cp++)
290 if (any(*cp, "=-+?")) {
291 c = *cp;
292 *cp++ = 0;
293 break;
295 if (s[1] == 0 && (*s == '*' || *s == '@')) {
296 if (dolc > 1) {
297 /* currently this does not distinguish $* and $@ */
298 /* should check dollar */
299 e.linep = s;
300 PUSHIO(awordlist, dolv+1, dolchar);
301 return(0);
302 } else { /* trap the nasty ${=} */
303 s[0] = '1';
304 s[1] = 0;
307 e.linep = s;
308 vp = lookup(s);
309 if ((dolp = vp->value) == null) {
310 switch (c) {
311 case '=':
312 if (digit(*s)) {
313 err("cannot use ${...=...} with $n");
314 gflg++;
315 break;
317 cp = evalstr(strsave(cp, areanum),DOSUB);
318 setval(vp, cp);
319 dolp = vp->value;
320 break;
322 case '-':
323 dolp = evalstr(strsave(cp, areanum),DOSUB);
324 break;
326 case '?':
327 if (*cp == 0) {
328 prs("missing value for ");
329 err(s);
330 } else
331 err(evalstr(strsave(cp, areanum),DOSUB));
332 gflg++;
333 break;
335 } else if (c == '+') {
336 dolp = evalstr(strsave(cp, areanum),DOSUB);
338 if (flag['u'] && dolp == null) {
339 prs("unset variable: ");
340 err(s);
341 gflg++;
343 PUSHIO(aword, dolp, quoted ? qstrchar : strchar);
344 return(0);
348 * Run the command in `...` and read its output.
350 static int
351 grave(quoted)
352 int quoted;
354 int otask;
355 struct io *oiop;
356 register char *cp,*s;
357 register int i,c;
358 int pf[2];
360 c = readc();
361 s = e.linep;
362 *e.linep++ = c;
363 oiop = e.iop;
364 otask = e.iop->task;
365 e.iop->task = XOTHER;
366 while ((c = subgetc('\'', 0))!=0 && c!='`')
367 if (e.linep < elinep)
368 *e.linep++ = c;
369 if (oiop == e.iop)
370 e.iop->task = otask;
371 if (c != '`') {
372 err("no closing `");
373 return(0);
375 if (openpipe(pf) < 0)
376 return(0);
377 if ((i = fork()) == -1) {
378 closepipe(pf);
379 err("try again");
380 return(0);
382 if (i != 0) {
383 e.linep = s;
384 close(pf[1]);
385 PUSHIO(afile, remap(pf[0]), quoted? qgravechar: gravechar);
386 return(1);
388 *e.linep = 0;
389 /* allow trapped signals */
390 for (i=0; i<_NSIG; i++)
391 if (ourtrap[i] && signal(i, SIG_IGN) != SIG_IGN)
392 signal(i, SIG_DFL);
393 dup2(pf[1], 1);
394 closepipe(pf);
395 flag['e'] = 0;
396 flag['v'] = 0;
397 flag['n'] = 0;
398 cp = strsave(e.linep = s, 0);
399 areanum = 1;
400 inithere();
401 freearea(areanum); /* free old space */
402 e.oenv = NULL;
403 e.iop = (e.iobase = iostack) - 1;
404 unquote(cp);
405 talking = 0;
406 PUSHIO(aword, cp, nlchar);
407 onecommand();
408 exit(1);
411 char *
412 unquote(as)
413 register char *as;
415 register char *s;
417 if ((s = as) != NULL)
418 while (*s)
419 *s++ &= ~QUOTE;
420 return(as);
423 /* -------- glob.c -------- */
424 /* #include "sh.h" */
427 * glob
430 #define scopy(x) strsave((x), areanum)
431 #define BLKSIZ 512
432 #define NDENT ((BLKSIZ+sizeof(struct direct)-1)/sizeof(struct direct))
434 static struct wdblock *cl, *nl;
435 static char spcl[] = "[?*";
437 struct wdblock *
438 glob(cp, wb)
439 char *cp;
440 struct wdblock *wb;
442 register i;
443 register char *pp;
445 if (cp == 0)
446 return(wb);
447 i = 0;
448 for (pp = cp; *pp; pp++)
449 if (any(*pp, spcl))
450 i++;
451 else if (!any(*pp & ~QUOTE, spcl))
452 *pp &= ~QUOTE;
453 if (i != 0) {
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);
460 break;
462 if (*pp == '\0')
463 nl = addword(scopy(cl->w_words[i]), nl);
465 for(i=0; i<cl->w_nword; i++)
466 DELETE(cl->w_words[i]);
467 DELETE(cl);
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);
472 if (cl->w_nword) {
473 for (i=0; i<cl->w_nword; i++)
474 wb = addword(cl->w_words[i], wb);
475 DELETE(cl);
476 return(wb);
479 wb = addword(unquote(cp), wb);
480 return(wb);
483 void
484 globname(we, pp)
485 char *we;
486 register char *pp;
488 register char *np, *cp;
489 char *name, *gp, *dp;
490 int dn, j, n, k;
491 struct direct ent[NDENT];
492 char dname[NAME_MAX+1];
493 struct stat dbuf;
495 for (np = we; np != pp; pp--)
496 if (pp[-1] == '/')
497 break;
498 for (dp = cp = space((int)(pp-np)+3); np < pp;)
499 *cp++ = *np++;
500 *cp++ = '.';
501 *cp = '\0';
502 for (gp = cp = space(strlen(pp)+1); *np && *np != '/';)
503 *cp++ = *np++;
504 *cp = '\0';
505 dn = open(dp, 0);
506 if (dn < 0) {
507 DELETE(dp);
508 DELETE(gp);
509 return;
511 dname[NAME_MAX] = '\0';
512 while ((n = read(dn, (char *)ent, sizeof(ent))) >= sizeof(*ent)) {
513 n /= sizeof(*ent);
514 for (j=0; j<n; j++) {
515 if (ent[j].d_ino == 0)
516 continue;
517 strncpy(dname, ent[j].d_name, NAME_MAX);
518 if (dname[0] == '.')
519 if (*gp != '.')
520 continue;
521 for(k=0; k<NAME_MAX; k++)
522 if (any(dname[k], spcl))
523 dname[k] |= QUOTE;
524 if (gmatch(dname, gp)) {
525 name = generate(we, pp, dname, np);
526 if (*np && !anys(np, spcl)) {
527 if (stat(name,&dbuf)) {
528 DELETE(name);
529 continue;
532 nl = addword(name, nl);
536 close(dn);
537 DELETE(dp);
538 DELETE(gp);
542 * generate a pathname as below.
543 * start..end1 / middle end
544 * the slashes come for free
546 static char *
547 generate(start1, end1, middle, end)
548 char *start1;
549 register char *end1;
550 char *middle, *end;
552 char *p;
553 register char *op, *xp;
555 p = op = space((int)(end1-start1)+strlen(middle)+strlen(end)+2);
556 for (xp = start1; xp != end1;)
557 *op++ = *xp++;
558 for (xp = middle; (*op++ = *xp++) != '\0';)
560 op--;
561 for (xp = end; (*op++ = *xp++) != '\0';)
563 return(p);
566 static int
567 anyspcl(wb)
568 register struct wdblock *wb;
570 register i;
571 register char **wd;
573 wd = wb->w_words;
574 for (i=0; i<wb->w_nword; i++)
575 if (anys(spcl, *wd++))
576 return(1);
577 return(0);
580 static int
581 xstrcmp(p1, p2)
582 char *p1, *p2;
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 */
593 struct wdblock *
594 newword(nw)
595 register int nw;
597 register struct wdblock *wb;
599 wb = (struct wdblock *) space(sizeof(*wb) + nw*sizeof(char *));
600 wb->w_bsize = nw;
601 wb->w_nword = 0;
602 return(wb);
605 struct wdblock *
606 addword(wd, wb)
607 char *wd;
608 register struct wdblock *wb;
610 register struct wdblock *wb2;
611 register nw;
613 if (wb == NULL)
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 *));
618 wb2->w_nword = nw;
619 DELETE(wb);
620 wb = wb2;
622 wb->w_words[wb->w_nword++] = wd;
623 return(wb);
626 char **
627 getwords(wb)
628 register struct wdblock *wb;
630 register char **wd;
631 register nb;
633 if (wb == NULL)
634 return((char **)NULL);
635 if (wb->w_nword == 0) {
636 DELETE(wb);
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 */
642 return(wd);
645 _PROTOTYPE(int (*func), (char *, char *));
646 int globv;
648 void
649 glob0(a0, a1, a2, a3)
650 char *a0;
651 unsigned a1;
652 int a2;
653 _PROTOTYPE(int (*a3), (char *, char *));
655 func = a3;
656 globv = a2;
657 glob1(a0, a0 + a1 * a2);
660 void
661 glob1(base, lim)
662 char *base, *lim;
664 register char *i, *j;
665 int v2;
666 char *lptr, *hptr;
667 int c;
668 unsigned n;
671 v2 = globv;
673 top:
674 if ((n=(int)(lim-base)) <= v2)
675 return;
676 n = v2 * (n / (2*v2));
677 hptr = lptr = base+n;
678 i = base;
679 j = lim-v2;
680 for(;;) {
681 if (i < lptr) {
682 if ((c = (*func)(i, lptr)) == 0) {
683 glob2(i, lptr -= v2);
684 continue;
686 if (c < 0) {
687 i += v2;
688 continue;
692 begin:
693 if (j > hptr) {
694 if ((c = (*func)(hptr, j)) == 0) {
695 glob2(hptr += v2, j);
696 goto begin;
698 if (c > 0) {
699 if (i == lptr) {
700 glob3(i, hptr += v2, j);
701 i = lptr += v2;
702 goto begin;
704 glob2(i, j);
705 j -= v2;
706 i += v2;
707 continue;
709 j -= v2;
710 goto begin;
714 if (i == lptr) {
715 if (lptr-base >= lim-hptr) {
716 glob1(hptr+v2, lim);
717 lim = lptr;
718 } else {
719 glob1(base, lptr);
720 base = hptr+v2;
722 goto top;
726 glob3(j, lptr -= v2, i);
727 j = hptr -= v2;
731 void
732 glob2(i, j)
733 char *i, *j;
735 register char *index1, *index2, c;
736 int m;
738 m = globv;
739 index1 = i;
740 index2 = j;
741 do {
742 c = *index1;
743 *index1++ = *index2;
744 *index2++ = c;
745 } while(--m);
748 void
749 glob3(i, j, k)
750 char *i, *j, *k;
752 register char *index1, *index2, *index3;
753 int c;
754 int m;
756 m = globv;
757 index1 = i;
758 index2 = j;
759 index3 = k;
760 do {
761 c = *index1;
762 *index1++ = *index3;
763 *index3++ = *index2;
764 *index2++ = c;
765 } while(--m);
768 char *
769 memcopy(ato, from, nb)
770 register char *ato, *from;
771 register int nb;
773 register char *to;
775 to = ato;
776 while (--nb >= 0)
777 *to++ = *from++;
778 return(ato);