void pexerr(void) { #ifdef TRACE tprintf("TRACE- pexerr()\n"); #endif /* Couldn't find the damn thing */ if (exerr) bferr(exerr); bferr("Command not found"); }
struct varent * getvx(tchar *vp, int subscr) { struct varent *v = adrof(vp); #ifdef TRACE tprintf("TRACE- getvx()\n"); #endif if (v == 0) udvar(vp); if (subscr < 1 || subscr > blklen(v->vec)) bferr("Subscript out of range"); return (v); }
tchar * getinx(tchar *cp, int *ip) { #ifdef TRACE tprintf("TRACE- getinx()\n"); #endif *ip = 0; *cp++ = 0; while (*cp && digit(*cp)) *ip = *ip * 10 + *cp++ - '0'; if (*cp++ != ']') bferr("Subscript error"); return (cp); }
/* * $ substitute one word, for i/o redirection */ tchar * Dfix1(tchar *cp) { tchar *Dv[2]; #ifdef TRACE tprintf("TRACE- Dfix1()\n"); #endif if (noexec) return (0); Dv[0] = cp; Dv[1] = NOSTR; Dfix2(Dv); if (gargc != 1) { setname(cp); bferr("Ambiguous"); } cp = savestr(gargv[0]); blkfree(gargv), gargv = 0; return (cp); }
/* * Form a shell temporary file (in unit 0) from the words * of the shell input up to a line the same as "term". * Unit 0 should have been closed before this call. */ void heredoc(tchar *term) { int c; tchar *Dv[2]; tchar obuf[BUFSIZ], lbuf[BUFSIZ], mbuf[BUFSIZ]; int ocnt, lcnt, mcnt; tchar *lbp, *obp, *mbp; tchar **vp; bool quoted; tchar shtemp[] = {'/', 't', 'm', 'p', '/', 's', 'h', 'X', 'X', 'X', 'X', 'X', 'X', 0}; int fd1; #ifdef TRACE tprintf("TRACE- heredoc()\n"); #endif if ((fd1 = mkstemp_(shtemp)) < 0) Perror(shtemp); (void) unlink_(shtemp); /* 0 0 inode! */ unsetfd(fd1); Dv[0] = term; Dv[1] = NOSTR; gflag = 0; trim(Dv); rscan(Dv, Dtestq); quoted = gflag; ocnt = BUFSIZ; obp = obuf; for (;;) { /* * Read up a line */ lbp = lbuf; lcnt = BUFSIZ - 4; for (;;) { c = readc(1); /* 1 -> Want EOF returns */ if (c < 0) { setname(term); bferr("<< terminator not found"); } if (c == '\n') break; if (c &= TRIM) { *lbp++ = c; if (--lcnt < 0) { setname(S_LESLES /* "<<" */); error("Line overflow"); } } } *lbp = 0; /* * Compare to terminator -- before expansion */ if (eq(lbuf, term)) { (void) write_(0, obuf, BUFSIZ - ocnt); (void) lseek(0, (off_t)0, 0); return; } /* * If term was quoted or -n just pass it on */ if (quoted || noexec) { *lbp++ = '\n'; *lbp = 0; for (lbp = lbuf; c = *lbp++; ) { *obp++ = c; if (--ocnt == 0) { (void) write_(0, obuf, BUFSIZ); obp = obuf; ocnt = BUFSIZ; } } continue; } /* * Term wasn't quoted so variable and then command * expand the input line */ Dcp = lbuf; Dvp = Dv + 1; mbp = mbuf; mcnt = BUFSIZ - 4; for (;;) { c = DgetC(DODOL); if (c == DEOF) break; if ((c &= TRIM) == 0) continue; /* \ quotes \ $ ` here */ if (c == '\\') { c = DgetC(0); /* if (!any(c, "$\\`")) */ if ((c != '$') && (c != '\\') && (c != '`')) unDgetC(c | QUOTE), c = '\\'; else c |= QUOTE; } *mbp++ = c; if (--mcnt == 0) { setname(S_LESLES /* "<<" */); bferr("Line overflow"); } } *mbp++ = 0; /* * If any ` in line do command substitution */ mbp = mbuf; if (any('`', mbp)) { /* * 1 arg to dobackp causes substitution to be literal. * Words are broken only at newlines so that all blanks * and tabs are preserved. Blank lines (null words) * are not discarded. */ vp = dobackp(mbuf, 1); } else /* Setup trivial vector similar to return of dobackp */ Dv[0] = mbp, Dv[1] = NOSTR, vp = Dv; /* * Resurrect the words from the command substitution * each separated by a newline. Note that the last * newline of a command substitution will have been * discarded, but we put a newline after the last word * because this represents the newline after the last * input line! */ for (; *vp; vp++) { for (mbp = *vp; *mbp; mbp++) { *obp++ = *mbp & TRIM; if (--ocnt == 0) { (void) write_(0, obuf, BUFSIZ); obp = obuf; ocnt = BUFSIZ; } } *obp++ = '\n'; if (--ocnt == 0) { (void) write_(0, obuf, BUFSIZ); obp = obuf; ocnt = BUFSIZ; } } if (pargv) blkfree(pargv), pargv = 0; } }
void doset(tchar **v) { tchar *p; tchar *vp, op; tchar **vecp; bool hadsub; int subscr; tchar *retp; #ifdef TRACE tprintf("TRACE- doset()\n"); #endif v++; p = *v++; if (p == 0) { prvars(); return; } do { hadsub = 0; /* * check for proper variable syntax * must be alphanumeric, start with a letter and * be at most 20 characters */ for (vp = p; alnum(*p); p++) continue; if (vp == p || !letter(*vp)) goto setsyn; if ((p - vp) > MAX_VAR_LEN) bferr("Variable name too long"); if (*p == '[') { hadsub++; p = getinx(p, &subscr); } if (op = *p) { *p++ = 0; if (*p == 0 && *v && **v == '(') p = *v++; } else if (*v && eq(*v, S_EQ /* "=" */)) { op = '=', v++; if (*v) p = *v++; } if (op && op != '=') setsyn: bferr("Syntax error"); if (eq(p, S_LPAR /* "(" */)) { tchar **e = v; if (hadsub) goto setsyn; for (;;) { if (!*e) bferr("Missing )"); if (**e == ')') break; e++; } p = *e; *e = 0; vecp = saveblk(v); set1(vp, vecp, &shvhed); *e = p; v = e + 1; } else if (hadsub) { retp = savestr(p); asx(vp, subscr, retp); xfree(retp); retp = 0; } else set(vp, savestr(p)); if (eq(vp, S_path /* "path" */)) { exportpath(adrof(S_path /* "path" */)->vec); dohash(xhash); } else if (eq(vp, S_histchars /* "histchars" */)) { tchar *p = value(S_histchars /* "histchars" */); HIST = *p++; HISTSUB = *p; } else if (eq(vp, S_user /* "user" */)) local_setenv(S_USER /* "USER" */, value(vp)); else if (eq(vp, S_term /* "term" */)) local_setenv(S_TERM /* "TERM" */, value(vp)); else if (eq(vp, S_home /* "home" */)) local_setenv(S_HOME /* "HOME" */, value(vp)); #ifdef FILEC else if (eq(vp, S_filec /* "filec" */)) filec = 1; else if (eq(vp, S_cdpath /* "cdpath" */)) dohash(xhash2); #endif } while (p = *v++); }
void dolet(tchar **v) { tchar *p; tchar *vp, c, op; bool hadsub; int subscr; v++; p = *v++; if (p == 0) { prvars(); return; } do { hadsub = 0; for (vp = p; alnum(*p); p++) continue; if (vp == p || !letter(*vp)) goto letsyn; if (*p == '[') { hadsub++; p = getinx(p, &subscr); } if (*p == 0 && *v) p = *v++; if (op = *p) *p++ = 0; else goto letsyn; vp = savestr(vp); if (op == '=') { c = '='; p = xset(p, &v); } else { c = *p++; /* if (any(c, "+-")) { */ if (c == '+' || c == '-') { if (c != op || *p) goto letsyn; p = plusplus; } else { /* if (any(op, "<>")) { */ if (op == '<' || op == '>') { if (c != op) goto letsyn; c = *p++; letsyn: bferr("Syntax error"); } if (c != '=') goto letsyn; p = xset(p, &v); } } if (op == '=') if (hadsub) asx(vp, subscr, p); else set(vp, p); else if (hadsub) #ifndef V6 /* avoid bug in vax CC */ { struct varent *gv = getvx(vp, subscr); asx(vp, subscr, operate(op, gv->vec[subscr - 1], p)); } #else asx(vp, subscr, operate(op, getvx(vp, subscr)->vec[subscr - 1], p)); #endif else set(vp, operate(op, value(vp), p)); if (eq(vp, S_path /* "path" */)) { exportpath(adrof(S_path /* "path" */)->vec); dohash(xhash); } if (eq(vp, S_cdpath /* "cdpath" */)) dohash(xhash2); xfree(vp); if (c != '=') xfree(p); } while (p = *v++);