sh.dol.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 768 行 · 第 1/2 页
C
768 行
*/ dolmod = 'q'; dolmcnt = 10000; setDolp(wbuf); goto eatbrac; case DEOF: case '\n': goto syntax; case '*': (void) strcpy(name, "argv"); vp = adrof("argv"); subscr = -1; /* Prevent eating [...] */ break; default: np = name; if (digit(c)) { if (dimen) goto syntax; /* No $#1, e.g. */ subscr = 0; do { subscr = subscr * 10 + c - '0'; c = DgetC(0); } while (digit(c)); unDredc(c); if (subscr < 0) goto oob; if (subscr == 0) { if (bitset) { dolp = file ? "1" : "0"; goto eatbrac; } if (file == 0) error("No file for $0"); setDolp(file); goto eatbrac; } if (bitset) goto syntax; vp = adrof("argv"); if (vp == 0) { vp = &nulargv; goto eatmod; } break; } /* GT01: must start with an alphabetic */ if (!letter(c)) goto syntax; for (;;) { *np++ = c; c = DgetC(0); if (!alnum(c)) break; if (np >= &name[sizeof name - 2])syntax: error("Variable syntax"); } *np++ = 0; unDredc(c); vp = adrof(name); } if (bitset) { dolp = (vp || getenv(name)) ? "1" : "0"; goto eatbrac; } if (vp == 0) { np = getenv(name); if (np) { addla(np); goto eatbrac; } udvar(name); /*NOTREACHED*/ } c = DgetC(0); upb = blklen(vp->vec); if (dimen == 0 && subscr == 0 && c == '[') { np = name; for (;;) { c = DgetC(DODOL); /* Allow $ expand within [ ] */ if (c == ']') break; if (c == '\n' || c == DEOF) goto syntax; if (np >= &name[sizeof name - 2]) goto syntax; *np++ = c; } *np = 0, np = name; if (dolp || dolcnt) /* $ exp must end before ] */ goto syntax; if (!*np) goto syntax; if (digit(*np)) { register int i = 0; while (digit(*np)) i = i * 10 + *np++ - '0'; if ((i < 0 || i > upb) && !any(*np, "-*")) {oob: setname(vp->v_name); error("Subscript out of range"); } lwb = i; if (!*np) upb = lwb, np = "*"; } if (*np == '*') np++; else if (*np != '-') goto syntax; else { register int i = upb; np++; if (digit(*np)) { i = 0; while (digit(*np)) i = i * 10 + *np++ - '0'; if (i < 0 || i > upb) goto oob; } if (i < lwb) upb = lwb - 1; else upb = i; } if (lwb == 0) { if (upb != 0) goto oob; upb = -1; } if (*np) goto syntax; } else { if (subscr > 0) if (subscr > upb) lwb = 1, upb = 0; else lwb = upb = subscr; unDredc(c); } if (dimen) { char *cp = putn(upb - lwb + 1); addla(cp); xfree(cp); } else {eatmod: c = DgetC(0); if (c == ':') { c = DgetC(0), dolmcnt = 1; if (c == 'g') c = DgetC(0), dolmcnt = 10000; if (!any(c, "htrqxe")) error("Bad : mod in $"); dolmod = c; if (c == 'q') dolmcnt = 10000; } else unDredc(c); dolnxt = &vp->vec[lwb - 1]; dolcnt = upb - lwb + 1; }eatbrac: if (sc == '{') { c = Dredc(); if (c != '}') goto syntax; }}setDolp(cp) register char *cp;{ register char *dp; if (dolmod == 0 || dolmcnt == 0) { dolp = cp; return; } dp = domod(cp, dolmod); if (dp) { dolmcnt--; addla(dp); xfree(dp); } else addla(cp); dolp = "";}unDredc(c) int c;{ Dpeekrd = c;}Dredc(){ register int c; if (c = Dpeekrd) { Dpeekrd = 0; return (c); } if (Dcp && (c = *Dcp++)) { if ((c & TRIM) == QUOTECHAR) c = (*Dcp++ & TRIM) | QUOTE; return (c&(QUOTE|TRIM)); } if (*Dvp == 0) { Dcp = 0; return (DEOF); } Dcp = *Dvp++; return (' ');}Dtestq(c) register int c;{ if (any(c, "\\'\"`")) gflag = 1;}/* * 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. */heredoc(term) char *term;{ register int c; char *Dv[2]; char obuf[BUFSIZ], lbuf[BUFSIZ], mbuf[BUFSIZ]; int ocnt, lcnt, mcnt; register char *lbp, *obp, *mbp; char **vp; bool quoted; if (creat(shtemp, 0600) < 0) Perror(shtemp); (void) close(0); if (open(shtemp, 2) < 0) { int oerrno = errno; (void) unlink(shtemp); errno = oerrno; Perror(shtemp); } (void) unlink(shtemp); /* 0 0 inode! */ 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 == (-1)) { /* ARG - compare correctly */ setname(term); bferr("<< terminator not found"); } if (c == '\n') break; if (c &= TRIM) { *lbp++ = c; if (--lcnt < 0) { setname("<<"); 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, "$\\`")) unDgetC(c | QUOTE), c = '\\'; else *mbp++ = QUOTECHAR, c |= QUOTE; /* 003 - GAG */ } *mbp++ = c & TRIM; /* 003 - GAG */ if (--mcnt == 0) { setname("<<"); bferr("Line overflow"); } } *mbp = 0; /* 003 - GAG */ /* * If any ` in line do command substitution */ for (mbp = mbuf; *mbp; mbp++) { if ((*mbp & TRIM) == QUOTECHAR) mbp++; else 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); break; } } if (!*mbp) { /* no ` in string; mbp points to NULL */ mbp = mbuf; /* 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! */ trim (vp); /* 003 - GAG */ 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; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?