sh.dol.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 768 行 · 第 1/2 页
C
768 行
#ifndef lintstatic char *sccsid = "@(#)sh.dol.c 4.1 (ULTRIX) 7/17/90";#endif/*********************************************************************** * * * Copyright (c) 1988 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* ------------------------------------------------------------------ *//* | Copyright Unpublished, MIPS Computer Systems, Inc. All Rights | *//* | Reserved. This software contains proprietary and confidential | *//* | information of MIPS and its suppliers. Use, disclosure or | *//* | reproduction is prohibited without the prior express written | *//* | consent of MIPS. | *//* ------------------------------------------------------------------ *//* $Header: sh.dol.c,v 1.3 86/07/11 10:29:59 dce Exp $ */#include "sh.h"/* * C shell * * Modification History * * 003 - Gary A. Gaudet - Wed Jan 31 13:09:35 EST 1990 * Fixed escape of command substitution and variable expansion * in heredoc rediction. * * 002 - Gary A. Gaudet - Thu Dec 28 17:43:59 EST 1989 * Added (castings). & TRIMming. * * 01 Sat Aug 13 15:28:57 EDT 1988, Gary A. Gaudet * merging mips & ultrix for 8 bit clean and bug fixes *//* * These routines perform variable substitution and quoting via ' and ". * To this point these constructs have been preserved in the divided * input words. Here we expand variables and turn quoting via ' and " into * QUOTE bits on characters (which prevent further interpretation). * If the `:q' modifier was applied during history expansion, then * some QUOTEing may have occurred already, so we dont "trim()" here. */int Dpeekc, Dpeekrd; /* Peeks for DgetC and Dreadc */char *Dcp, **Dvp; /* Input vector for Dreadc */#define DEOF -1#define unDgetC(c) Dpeekc = c#define QUOTES (_Q|_Q1|_ESC) /* \ ' " ` *//* * The following variables give the information about the current * $ expansion, recording the current word position, the remaining * words within this expansion, the count of remaining words, and the * information about any : modifier which is being applied. */char *dolp; /* Remaining chars from this word */char **dolnxt; /* Further words */int dolcnt; /* Count of further words */char dolmod; /* : modifier character */int dolmcnt; /* :gx -> 10000, else 1 *//* * Fix up the $ expansions and quotations in the * argument list to command t. */Dfix(t) register struct command *t;{ register char **pp; register char *p; if (noexec) return; /* Note that t_dcom isn't trimmed thus !...:q's aren't lost */ for (pp = t->t_dcom; p = *pp++;) while (*p) if (cmap(*p++, _DOL|QUOTES)) { /* $, \, ', ", ` */ Dfix2(t->t_dcom); /* found one */ blkfree(t->t_dcom); t->t_dcom = gargv; gargv = 0; return; }}/* * $ substitute one word, for i/o redirection */char *Dfix1(cp) register char *cp;{ char *Dv[2]; 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);}/* * Subroutine to do actual fixing after state initialization. */Dfix2(v) char **v;{ char *agargv[GAVSIZ]; ginit(agargv); /* Initialize glob's area pointers */ Dvp = v; Dcp = ""; /* Setup input vector for Dreadc */ unDgetC(0); unDredc(0); /* Clear out any old peeks (at error) */ dolp = 0; dolcnt = 0; /* Clear out residual $ expands (...) */ while (Dword()) continue; gargv = copyblk(gargv);}/* * Get a word. This routine is analogous to the routine * word() in sh.lex.c for the main lexical input. One difference * here is that we don't get a newline to terminate our expansion. * Rather, DgetC will return a DEOF when we hit the end-of-input. */Dword(){ register int c, c1; char wbuf[BUFSIZ*2]; register char *wp = wbuf; register int i = BUFSIZ*2 - 4*2; register bool dolflg; bool sofar = 0;loop: c = DgetC(DODOL); switch (c) { case DEOF:deof: if (sofar == 0) return (0); /* finish this word and catch the code above the next time */ unDredc(c); /* fall into ... */ case '\n': *wp = 0; goto ret; case ' ': case '\t': goto loop; case '`': /* We preserve ` quotations which are done yet later */ *wp++ = c, --i; case '\'': case '"': /* * Note that DgetC never returns a QUOTES character * from an expansion, so only true input quotes will * get us here or out. */ c1 = c; dolflg = c1 == '"' ? DODOL : 0; for (;;) { c = DgetC(dolflg); if (c == c1) break; if (c == '\n' || c == DEOF) error("Unmatched %c", c1); if ((c & (QUOTE|TRIM)) == ('\n' | QUOTE)) /* * backout the previous character and its * QUOTECHAR */ wp -= 2, i +=2; if (--i <= 0) goto toochars; switch (c1) { case '"': /* * Leave any `s alone for later. * Other chars are all quoted, thus `...` * can tell it was within "...". */ if (c != '`') { *wp++ = QUOTECHAR; i--; } *wp++ = c; break; case '\'': /* Prevent all further interpretation */ *wp++ = (char) QUOTECHAR; /* 002 - GAG */ i--; *wp++ = c; break; case '`': /* Leave all text alone for later */ *wp++ = c; break; } } if (c1 == '`') *wp++ = '`', --i; goto pack; /* continue the word */ case '\\': c = DgetC(0); /* No $ subst! */ if (c == '\n' || c == DEOF) goto loop; c |= QUOTE; break; } unDgetC(c);pack: sofar = 1; /* pack up more characters in this word */ for (;;) { c = DgetC(DODOL); if (c == '\\') { c = DgetC(0); if (c == DEOF) goto deof; if (c == '\n') c = ' '; else c |= QUOTE; } if (c == DEOF) goto deof; if (any(c," \t\n'\"`")) { /* sp \t\n'"` */ unDgetC(c); if (any(c, "\\'\"`")) goto loop; *wp++ = 0; goto ret; } if (--i <= 0)toochars: error("Word too long"); if (c & QUOTE) { *(unsigned char *)wp++ = QUOTECHAR; /* 002 - GAG */ i--; } *wp++ = c & TRIM; /* 002 - GAG */ }ret: Gcat("", wbuf); return (1);}/* * Get a character, performing $ substitution unless flag is 0. * Any QUOTES character which is returned from a $ expansion is * QUOTEd so that it will not be recognized above. */DgetC(flag) register int flag;{ register int c;top: if (c = Dpeekc) { Dpeekc = 0; return (c); } if (lap) { if (((c = *lap++) & TRIM) == QUOTECHAR) c = (*lap++ & TRIM) | QUOTE; /* GAG - fix "set a=$<" */ if (c == 0) { lap = 0; goto top; }quotspec: if (any(c, "\\'\"`")) return (c | QUOTE); return (c); } if (dolp) { if (((c = *dolp++) & TRIM) == QUOTECHAR) c = (*dolp++ & TRIM) | QUOTE; /* GAG - fix "set a=$<" */ if (c & (QUOTE|TRIM)) goto quotspec; if (dolcnt > 0) { setDolp(*dolnxt++); --dolcnt; return (' '); } dolp = 0; } if (dolcnt > 0) { setDolp(*dolnxt++); --dolcnt; goto top; } c = Dredc(); if (c == '$' && flag) { Dgetdol(); goto top; } return (c);}char *nulvec[] = { 0 };struct varent nulargv = { nulvec, "argv", 0 };/* * Handle the multitudinous $ expansion forms. * Ugh. */Dgetdol(){ register char *np; register struct varent *vp; char name[20]; int c, sc; int subscr = 0, lwb = 1, upb = 0; bool dimen = 0, bitset = 0; char wbuf[BUFSIZ]; dolmod = dolmcnt = 0; c = sc = DgetC(0); if (c == '{') c = DgetC(0); /* sc is { to take } later */ if ((c & TRIM) == '#') dimen++, c = DgetC(0); /* $# takes dimension */ else if (c == '?') bitset++, c = DgetC(0); /* $? tests existence */ switch (c) { case '$': if (dimen || bitset) goto syntax; /* No $?$, $#$ */ setDolp(doldol); goto eatbrac; case '<'|QUOTE: if (dimen || bitset) goto syntax; /* No $?<, $#< */ for (np = wbuf; read(OLDSTD, np, 1) == 1; np++) { if (np >= &wbuf[BUFSIZ-1]) error("$< line too long"); if (*np <= 0 || *np == '\n') break; } *np = 0; /* * KLUDGE: dolmod is set here because it will * cause setDolp to call domod and thus to copy wbuf. * Otherwise setDolp would use it directly. If we saved * it ourselves, no one would know when to free it. * The actual function of the 'q' causes filename * expansion not to be done on the interpolated value.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?