📄 ash.c
字号:
};struct nhere { int type; union node *next; int fd; union node *doc;};struct nnot { int type; union node *com;};union node { int type; struct ncmd ncmd; struct npipe npipe; struct nredir nredir; struct nbinary nbinary; struct nif nif; struct nfor nfor; struct ncase ncase; struct nclist nclist; struct narg narg; struct nfile nfile; struct ndup ndup; struct nhere nhere; struct nnot nnot;};struct nodelist { struct nodelist *next; union node *n;};struct funcnode { int count; union node n;};static void freefunc(struct funcnode *);/* $NetBSD: parser.h,v 1.15 2002/11/24 22:35:42 christos Exp $ *//* control characters in argument strings */#define CTL_FIRST '\201' /* first 'special' character */#define CTLESC '\201' /* escape next character */#define CTLVAR '\202' /* variable defn */#define CTLENDVAR '\203'#define CTLBACKQ '\204'#define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes *//* CTLBACKQ | CTLQUOTE == '\205' */#define CTLARI '\206' /* arithmetic expression */#define CTLENDARI '\207'#define CTLQUOTEMARK '\210'#define CTL_LAST '\210' /* last 'special' character *//* variable substitution byte (follows CTLVAR) */#define VSTYPE 0x0f /* type of variable substitution */#define VSNUL 0x10 /* colon--treat the empty string as unset */#define VSQUOTE 0x80 /* inside double quotes--suppress splitting *//* values of VSTYPE field */#define VSNORMAL 0x1 /* normal variable: $var or ${var} */#define VSMINUS 0x2 /* ${var-text} */#define VSPLUS 0x3 /* ${var+text} */#define VSQUESTION 0x4 /* ${var?message} */#define VSASSIGN 0x5 /* ${var=text} */#define VSTRIMRIGHT 0x6 /* ${var%pattern} */#define VSTRIMRIGHTMAX 0x7 /* ${var%%pattern} */#define VSTRIMLEFT 0x8 /* ${var#pattern} */#define VSTRIMLEFTMAX 0x9 /* ${var##pattern} */#define VSLENGTH 0xa /* ${#var} *//* values of checkkwd variable */#define CHKALIAS 0x1#define CHKKWD 0x2#define CHKNL 0x4#define IBUFSIZ (BUFSIZ + 1)/* * NEOF is returned by parsecmd when it encounters an end of file. It * must be distinct from NULL, so we use the address of a variable that * happens to be handy. */static int plinno = 1; /* input line number *//* number of characters left in input buffer */static int parsenleft; /* copy of parsefile->nleft */static int parselleft; /* copy of parsefile->lleft *//* next character in input buffer */static char *parsenextc; /* copy of parsefile->nextc */struct strpush { struct strpush *prev; /* preceding string on stack */ char *prevstring; int prevnleft;#ifdef CONFIG_ASH_ALIAS struct alias *ap; /* if push was associated with an alias */#endif char *string; /* remember the string since it may change */};struct parsefile { struct parsefile *prev; /* preceding file on stack */ int linno; /* current line */ int fd; /* file descriptor (or -1 if string) */ int nleft; /* number of chars left in this line */ int lleft; /* number of chars left in this buffer */ char *nextc; /* next char in buffer */ char *buf; /* input buffer */ struct strpush *strpush; /* for pushing strings at this level */ struct strpush basestrpush; /* so pushing one is fast */};static struct parsefile basepf; /* top level input file */static char basebuf[IBUFSIZ]; /* buffer for top level input file */static struct parsefile *parsefile = &basepf; /* current input file */static int tokpushback; /* last token pushed back */#define NEOF ((union node *)&tokpushback)static int parsebackquote; /* nonzero if we are inside backquotes */static int doprompt; /* if set, prompt the user */static int needprompt; /* true if interactive and at start of line */static int lasttoken; /* last token read */static char *wordtext; /* text of last word returned by readtoken */static int checkkwd;static struct nodelist *backquotelist;static union node *redirnode;static struct heredoc *heredoc;static int quoteflag; /* set if (part of) last token was quoted */static int startlinno; /* line # where last token started */static union node *parsecmd(int);static void fixredir(union node *, const char *, int);static const char *const *findkwd(const char *);static char *endofname(const char *);/* $NetBSD: shell.h,v 1.16 2003/01/22 20:36:04 dsl Exp $ */typedef void *pointer;static char nullstr[1]; /* zero length string */static const char spcstr[] = " ";static const char snlfmt[] = "%s\n";static const char dolatstr[] = { CTLVAR, VSNORMAL|VSQUOTE, '@', '=', '\0' };static const char illnum[] = "Illegal number: %s";static const char homestr[] = "HOME";#ifdef DEBUG#define TRACE(param) trace param#define TRACEV(param) tracev param#else#define TRACE(param)#define TRACEV(param)#endif#if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)#define __builtin_expect(x, expected_value) (x)#endif#define likely(x) __builtin_expect((x),1)#define TEOF 0#define TNL 1#define TREDIR 2#define TWORD 3#define TSEMI 4#define TBACKGND 5#define TAND 6#define TOR 7#define TPIPE 8#define TLP 9#define TRP 10#define TENDCASE 11#define TENDBQUOTE 12#define TNOT 13#define TCASE 14#define TDO 15#define TDONE 16#define TELIF 17#define TELSE 18#define TESAC 19#define TFI 20#define TFOR 21#define TIF 22#define TIN 23#define TTHEN 24#define TUNTIL 25#define TWHILE 26#define TBEGIN 27#define TEND 28/* first char is indicating which tokens mark the end of a list */static const char *const tokname_array[] = { "\1end of file", "\0newline", "\0redirection", "\0word", "\0;", "\0&", "\0&&", "\0||", "\0|", "\0(", "\1)", "\1;;", "\1`",#define KWDOFFSET 13 /* the following are keywords */ "\0!", "\0case", "\1do", "\1done", "\1elif", "\1else", "\1esac", "\1fi", "\0for", "\0if", "\0in", "\1then", "\0until", "\0while", "\0{", "\1}",};static const char *tokname(int tok){ static char buf[16]; if (tok >= TSEMI) buf[0] = '"'; sprintf(buf + (tok >= TSEMI), "%s%c", tokname_array[tok] + 1, (tok >= TSEMI ? '"' : 0)); return buf;}/* $NetBSD: machdep.h,v 1.10 2002/10/07 14:26:08 christos Exp $ *//* * Most machines require the value returned from malloc to be aligned * in some way. The following macro will get this right on many machines. */#define SHELL_SIZE (sizeof(union {int i; char *cp; double d; }) - 1)/* * It appears that grabstackstr() will barf with such alignments * because stalloc() will return a string allocated in a new stackblock. */#define SHELL_ALIGN(nbytes) (((nbytes) + SHELL_SIZE) & ~SHELL_SIZE)/* * This file was generated by the mksyntax program. *//* Syntax classes */#define CWORD 0 /* character is nothing special */#define CNL 1 /* newline character */#define CBACK 2 /* a backslash character */#define CSQUOTE 3 /* single quote */#define CDQUOTE 4 /* double quote */#define CENDQUOTE 5 /* a terminating quote */#define CBQUOTE 6 /* backwards single quote */#define CVAR 7 /* a dollar sign */#define CENDVAR 8 /* a '}' character */#define CLP 9 /* a left paren in arithmetic */#define CRP 10 /* a right paren in arithmetic */#define CENDFILE 11 /* end of file */#define CCTL 12 /* like CWORD, except it must be escaped */#define CSPCL 13 /* these terminate a word */#define CIGN 14 /* character should be ignored */#ifdef CONFIG_ASH_ALIAS#define SYNBASE 130#define PEOF -130#define PEOA -129#define PEOA_OR_PEOF PEOA#else#define SYNBASE 129#define PEOF -129#define PEOA_OR_PEOF PEOF#endif#define is_digit(c) ((unsigned)((c) - '0') <= 9)#define is_name(c) ((c) == '_' || isalpha((unsigned char)(c)))#define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c)))/* * is_special(c) evaluates to 1 for c in "!#$*-0123456789?@"; 0 otherwise * (assuming ascii char codes, as the original implementation did) */#define is_special(c) \ ( (((unsigned int)c) - 33 < 32) \ && ((0xc1ff920dUL >> (((unsigned int)c) - 33)) & 1))#define digit_val(c) ((c) - '0')/* * This file was generated by the mksyntax program. */#ifdef CONFIG_ASH_OPTIMIZE_FOR_SIZE#define USE_SIT_FUNCTION#endif/* number syntax index */#define BASESYNTAX 0 /* not in quotes */#define DQSYNTAX 1 /* in double quotes */#define SQSYNTAX 2 /* in single quotes */#define ARISYNTAX 3 /* in arithmetic */#ifdef CONFIG_ASH_MATH_SUPPORTstatic const char S_I_T[][4] = {#ifdef CONFIG_ASH_ALIAS {CSPCL, CIGN, CIGN, CIGN}, /* 0, PEOA */#endif {CSPCL, CWORD, CWORD, CWORD}, /* 1, ' ' */ {CNL, CNL, CNL, CNL}, /* 2, \n */ {CWORD, CCTL, CCTL, CWORD}, /* 3, !*-/:=?[]~ */ {CDQUOTE, CENDQUOTE, CWORD, CWORD}, /* 4, '"' */ {CVAR, CVAR, CWORD, CVAR}, /* 5, $ */ {CSQUOTE, CWORD, CENDQUOTE, CWORD}, /* 6, "'" */ {CSPCL, CWORD, CWORD, CLP}, /* 7, ( */ {CSPCL, CWORD, CWORD, CRP}, /* 8, ) */ {CBACK, CBACK, CCTL, CBACK}, /* 9, \ */ {CBQUOTE, CBQUOTE, CWORD, CBQUOTE}, /* 10, ` */ {CENDVAR, CENDVAR, CWORD, CENDVAR}, /* 11, } */#ifndef USE_SIT_FUNCTION {CENDFILE, CENDFILE, CENDFILE, CENDFILE}, /* 12, PEOF */ {CWORD, CWORD, CWORD, CWORD}, /* 13, 0-9A-Za-z */ {CCTL, CCTL, CCTL, CCTL} /* 14, CTLESC ... */#endif};#elsestatic const char S_I_T[][3] = {#ifdef CONFIG_ASH_ALIAS {CSPCL, CIGN, CIGN}, /* 0, PEOA */#endif {CSPCL, CWORD, CWORD}, /* 1, ' ' */ {CNL, CNL, CNL}, /* 2, \n */ {CWORD, CCTL, CCTL}, /* 3, !*-/:=?[]~ */ {CDQUOTE, CENDQUOTE, CWORD}, /* 4, '"' */ {CVAR, CVAR, CWORD}, /* 5, $ */ {CSQUOTE, CWORD, CENDQUOTE}, /* 6, "'" */ {CSPCL, CWORD, CWORD}, /* 7, ( */ {CSPCL, CWORD, CWORD}, /* 8, ) */ {CBACK, CBACK, CCTL}, /* 9, \ */ {CBQUOTE, CBQUOTE, CWORD}, /* 10, ` */ {CENDVAR, CENDVAR, CWORD}, /* 11, } */#ifndef USE_SIT_FUNCTION {CENDFILE, CENDFILE, CENDFILE}, /* 12, PEOF */ {CWORD, CWORD, CWORD}, /* 13, 0-9A-Za-z */ {CCTL, CCTL, CCTL} /* 14, CTLESC ... */#endif};#endif /* CONFIG_ASH_MATH_SUPPORT */#ifdef USE_SIT_FUNCTION#define U_C(c) ((unsigned char)(c))static int SIT(int c, int syntax){ static const char spec_symbls[] = "\t\n !\"$&'()*-/:;<=>?[\\]`|}~";#ifdef CONFIG_ASH_ALIAS static const char syntax_index_table[] = { 1, 2, 1, 3, 4, 5, 1, 6, /* "\t\n !\"$&'" */ 7, 8, 3, 3, 3, 3, 1, 1, /* "()*-/:;<" */ 3, 1, 3, 3, 9, 3, 10, 1, /* "=>?[\\]`|" */ 11, 3 /* "}~" */ };#else static const char syntax_index_table[] = { 0, 1, 0, 2, 3, 4, 0, 5, /* "\t\n !\"$&'" */ 6, 7, 2, 2, 2, 2, 0, 0, /* "()*-/:;<" */ 2, 0, 2, 2, 8, 2, 9, 0, /* "=>?[\\]`|" */ 10, 2 /* "}~" */ };#endif const char *s; int indx; if (c == PEOF) /* 2^8+2 */ return CENDFILE;#ifdef CONFIG_ASH_ALIAS if (c == PEOA) /* 2^8+1 */ indx = 0; else#endif if (U_C(c) >= U_C(CTLESC) && U_C(c) <= U_C(CTLQUOTEMARK)) return CCTL; else { s = strchr(spec_symbls, c); if (s == 0 || *s == 0) return CWORD; indx = syntax_index_table[(s - spec_symbls)]; } return S_I_T[indx][syntax];}#else /* USE_SIT_FUNCTION */#define SIT(c, syntax) S_I_T[(int)syntax_index_table[((int)c)+SYNBASE]][syntax]#ifdef CONFIG_ASH_ALIAS#define CSPCL_CIGN_CIGN_CIGN 0#define CSPCL_CWORD_CWORD_CWORD 1#define CNL_CNL_CNL_CNL 2#define CWORD_CCTL_CCTL_CWORD 3#define CDQUOTE_CENDQUOTE_CWORD_CWORD 4#define CVAR_CVAR_CWORD_CVAR 5#define CSQUOTE_CWORD_CENDQUOTE_CWORD 6#define CSPCL_CWORD_CWORD_CLP 7#define CSPCL_CWORD_CWORD_CRP 8#define CBACK_CBACK_CCTL_CBACK 9#define CBQUOTE_CBQUOTE_CWORD_CBQUOTE 10#define CENDVAR_CENDVAR_CWORD_CENDVAR 11#define CENDFILE_CENDFILE_CENDFILE_CENDFILE 12#define CWORD_CWORD_CWORD_CWORD 13#define CCTL_CCTL_CCTL_CCTL 14#else#define CSPCL_CWORD_CWORD_CWORD 0#define CNL_CNL_CNL_CNL 1#define CWORD_CCTL_CCTL_CWORD 2#define CDQUOTE_CENDQUOTE_CWORD_CWORD 3#define CVAR_CVAR_CWORD_CVAR 4#define CSQUOTE_CWORD_CENDQUOTE_CWORD 5#define CSPCL_CWORD_CWORD_CLP 6#define CSPCL_CWORD_CWORD_CRP 7#define CBACK_CBACK_CCTL_CBACK 8#define CBQUOTE_CBQUOTE_CWORD_CBQUOTE 9#define CENDVAR_CENDVAR_CWORD_CENDVAR 10#define CENDFILE_CENDFILE_CENDFILE_CENDFILE 11#define CWORD_CWORD_CWORD_CWORD 12#define CCTL_CCTL_CCTL_CCTL 13#endifstatic const char syntax_index_table[258] = { /* BASESYNTAX_DQSYNTAX_SQSYNTAX_ARISYNTAX */ /* 0 PEOF */ CENDFILE_CENDFILE_CENDFILE_CENDFILE,#ifdef CONFIG_ASH_ALIAS /* 1 PEOA */ CSPCL_CIGN_CIGN_CIGN,#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -