From e9ff1c6fbbbac9ece2604876ab589ac282360446 Mon Sep 17 00:00:00 2001 From: Nicholas Date: Mon, 15 Nov 2021 15:08:03 -0800 Subject: Feat: added if/else branching and switch statement Unsure about my modification to the language. I found the parsing of the case body within switches to be odd - specifically that it parses liberally and then checks that it has case -> cmd structuring while it walks the code. This means the language is more permissive than the semantics. I modified it to be more explicit, but at the cost of having to end each case statement with a semicolon. I wanted a colon, but this is a valid word character and thus will be lexed as part of the word. --- src/cmd/rc/code.c | 83 ++++++- src/cmd/rc/exec.c | 63 ++++- src/cmd/rc/exec.h | 2 + src/cmd/rc/glob.c | 82 +++++++ src/cmd/rc/lex.c | 16 +- src/cmd/rc/main.c | 3 +- src/cmd/rc/parse.c | 675 ++++++++++++++++++++++++++-------------------------- src/cmd/rc/parse.h | 47 +--- src/cmd/rc/rc.h | 7 +- src/cmd/rc/rules.mk | 3 +- src/cmd/rc/syntax.y | 38 ++- src/cmd/rc/wait.c | 25 +- 12 files changed, 616 insertions(+), 428 deletions(-) create mode 100644 src/cmd/rc/glob.c (limited to 'src') diff --git a/src/cmd/rc/code.c b/src/cmd/rc/code.c index 786f284..7077a0e 100644 --- a/src/cmd/rc/code.c +++ b/src/cmd/rc/code.c @@ -38,12 +38,14 @@ storepc(int a) interpreter.code[a].i = interpreter.i; } +void yyerror(const char *msg); + static void walk(Tree *node) { - Tree *n; - int addr1, addr2; + Tree *n, *c; + int addr1, addr2, addr3; if(!node) return; @@ -127,6 +129,7 @@ walk(Tree *node) case Tbang: walk(node->child[0]); emitf(Xbang); + break; case Tword: emitf(Xword); @@ -164,17 +167,78 @@ walk(Tree *node) node = n; break; /* control structures */ + case Tif: + walk(node->child[0]); // condition + emitf(Xtrue); + addr1 = emiti(0); + walk(node->child[1]); // if body + if(!node->child[2]) // no else + storepc(addr1); + else{ + emitf(Xgoto); + addr2 = emiti(0); + storepc(addr1); + walk(node->child[2]); + storepc(addr2); + } + break; + + case Tswitch: + /* NOTE: + * there are 3 addresses to store + * 1. addr1 = address to next case + * 2. addr2 = address to jump end instruction + * 3. addr3 = address of switch end + */ + emitf(Xmark); + walk(node->child[0]); // word we match to + emitf(Xgoto); // next case + addr1 = emiti(0); + addr2 = emitf(Xgoto); // switch end + addr3 = emiti(0); + storepc(addr1); + + // XXX: anyway to make this explicit in parser? + if(!(n = node->child[1])) + yyerror("empty switch statement"); + + emitcase: + if(!n) + goto donecase; + else if(n->type == ';'){ + c = n->child[0]; + n = n->child[1]; + }else if(n->type == Tcase){ + c = n; + n = nil; + }else + panicf("bad node type %d\n", n->type); + + emitf(Xmark); + walk(c->child[0]); // words + emitf(Xcase); + addr1 = emiti(0); // next case + walk(c->child[1]); // commands + emitf(Xgoto); + emiti(addr2); + storepc(addr1); + + goto emitcase; + donecase: + storepc(addr3); + break; + case Twhile: - addr1 = interpreter.i; // head of loop + addr1 = interpreter.i; // head of loop walk(node->child[0]); - if(addr1 == interpreter.i) - fatal("TODO"); + if(addr1 == interpreter.i) // empty condition => while(true) + emitf(Xsettrue); emitf(Xtrue); - addr2 = emiti(0); // goto end of loop + addr2 = emiti(0); // goto end of loop walk(node->child[1]); emitf(Xgoto); - emiti(addr1); // goto top of loop + emiti(addr1); // goto top of loop storepc(addr2); break; @@ -184,7 +248,10 @@ walk(Tree *node) walk(node->child[1]); // emitf(Xglob) }else{ // for(X) - fatal("TODO"); + emitf(Xmark); + emitf(Xword); + emits(strdup("*")); + emitf(Xdollar); } emitf(Xmark); // null initial value for Xlocal emitf(Xmark); diff --git a/src/cmd/rc/exec.c b/src/cmd/rc/exec.c index 5baaf1a..a551d52 100644 --- a/src/cmd/rc/exec.c +++ b/src/cmd/rc/exec.c @@ -360,6 +360,18 @@ count(Word *w) // ----------------------------------------------------------------------- // builtins +static void +setstatus(char *msg) +{ + if(!msg || msg[0] == 0) + runner->status = 0; + else + runner->status = 1; +} + +// ----------------------------------------------------------------------- +// builtins + void xecho(void) { @@ -402,10 +414,13 @@ xexit(void) Word *arg; popword(); // exit + arg = runner->args->word; switch(count(arg)){ default: print(shell.err, "invalid number of arguments to exit, exiting anyways\n"); + case 1: + setstatus(runner->args->word->str); case 0: Xexit(); } @@ -420,19 +435,24 @@ xcd(void) char dir[512]; popword(); // cd + setstatus(nil); arg = runner->args->word; switch(count(arg)){ default: print(shell.err, "usage: cd [directory]\n"); + setstatus("failed cd"); break; case 0: arg = var("home")->val; if(count(arg) >= 1){ - if(chdir(arg->str) < 0) + if(chdir(arg->str) < 0){ print(shell.err, "failed cd: %s\n", strerror(errno)); + setstatus("failed cd"); + } }else{ print(shell.err, "ambiguous cd: $home empty\n"); + setstatus("failed cd"); } break; @@ -443,9 +463,12 @@ xcd(void) strcpy(dir, cdpath->str); if(dir[0]) strcat(dir,"/"); + strcat(dir, arg->str); + if(chdir(dir) < 0){ print(shell.err, "failed cd %s: %s\n", dir, strerror(errno)); + setstatus("failed cd"); } break; } @@ -510,6 +533,8 @@ xdot(void) if(fd<0){ print(shell.err, "failed open: %s: ", base); + setstatus("failed open"); + Xerror(".: failed open"); return; } /* set up for a new command loop */ @@ -632,13 +657,21 @@ Xword(void) pushword(runner->code.exe[runner->code.i++].s); } +void +Xsettrue(void) +{ + setstatus(nil); +} + void Xtrue(void) { if(!runner->status){ - assert(runner->wait.status == Pdone); runner->code.i++; - deljob(runner); + if(runner->wait.status){ + assert(runner->wait.status == Pdone); + deljob(runner); + } runner->pgid = -1; }else runner->code.i = runner->code.exe[runner->code.i].i; @@ -662,6 +695,27 @@ Xgoto(void) runner->code.i = runner->code.exe[runner->code.i].i; } +void +Xcase(void) +{ + Word *p; // pattern + Word *c; // case value + + for(p=runner->args->word; p; p=p->link){ + for(c=runner->args->link->word; c; c=c->link){ + if(match(c->str, p->str, 0)) + goto hit; + } + } +nohit: + runner->code.i = runner->code.exe[runner->code.i].i; + goto clean; +hit: + runner->code.i++; +clean: + poplist(); // pop case words +} + void Xfor(void) { @@ -678,7 +732,6 @@ Xfor(void) runner->local->val->link = nil; runner->code.i++; } - } static @@ -1261,6 +1314,8 @@ Xerror(char *msg) { print(shell.err, "rc: %s", msg); flush(shell.err); + + setstatus("error"); while(!runner->flag.user) Xreturn(); } diff --git a/src/cmd/rc/exec.h b/src/cmd/rc/exec.h index a3a6ae9..78250f1 100644 --- a/src/cmd/rc/exec.h +++ b/src/cmd/rc/exec.h @@ -7,6 +7,7 @@ * code in line with jump around {...} */ +void Xcase(void); void Xmark(void); // Xmark marks stack location for word void Xindex(void); // Xindex void Xlocal(void); // Xlocal(name,val) create local variable, assign value @@ -22,6 +23,7 @@ void Xbang(void); void Xasync(void); void Xbasic(void); // Xbasic(args) run command and wait for result void Xsubshell(void); +void Xsettrue(void); void Xword(void); void Xjoin(void); void Xconcatenate(void); diff --git a/src/cmd/rc/glob.c b/src/cmd/rc/glob.c new file mode 100644 index 0000000..9d88b59 --- /dev/null +++ b/src/cmd/rc/glob.c @@ -0,0 +1,82 @@ +#include "rc.h" + +/* removes glob marks in place */ +void +deglob(char *s) +{ + char *t = s; + do{ + if(*t==GLOB) + t++; + *s++=*t; + }while(*t++); +} + +int +match(char *s, char *p, int stop) +{ + rune rs, rp, lo, hi; + int neg, hit; + + utf8·decode(p, &rp), utf8·decode(s, &rs); + for(; *p && *p != stop; s+=utf8·decode(s,&rs),p+=utf8·decode(p,&rp)){ + /* fast path: normal character */ + if(*p != GLOB){ + if(rp != rs) + return 0; + continue; + } + + /* unglob */ + switch(*++p){ + case GLOB: + if(*s != GLOB) + return 0; + break; + case '*': + for(;;){ + p += utf8·decode(p, &rp); + if(match(s, p, stop)) + return 1; + s += utf8·decode(s, &rs); + } + return 0; + + case '?': + if(*s == 0) + return 0; + break; + + case '[': + if(*s==0) + return 0; + if((neg=*++p=='~')) + p++; + hit = 0; + while(*p != ']'){ + if(*p==0) + return 0; /* syntax error */ + p += utf8·decode(p, &lo); + if(*p != '-') + hi = lo; + else{ + if(*++p == 0) + return 0; /* syntax error */ + p += utf8·decode(p, &hi); + if(hi < lo) + rp=lo, lo=hi, hi=rp; + } + + if(lo <= rs && rs <= hi) + hit = 1; + } + if(neg) + hit=!hit; + if(!hit) + return 0; + break; + } + } + + return *s == 0; +} diff --git a/src/cmd/rc/lex.c b/src/cmd/rc/lex.c index 9ca2453..3722606 100644 --- a/src/cmd/rc/lex.c +++ b/src/cmd/rc/lex.c @@ -142,8 +142,7 @@ putbyte(char *buf, int c) return buf; } -static -char * +static char * putrune(char *buf, int c) { buf = putbyte(buf, c); @@ -184,7 +183,7 @@ isidentchar(int c) int yylex(void) { - int c, d = peekc(); + int c, d = peekc(); Tree *node; char *w = lexer.buf; @@ -369,8 +368,15 @@ yylex(void) } for(;;){ - w = putrune(w, c); - c = peekc(); + switch(c){ + /* inject a magic glob character into our stream */ + case '*': case '[': case '?': case (int)GLOB: + w = putbyte(w, GLOB); + /* fallthrough */ + default: + w = putrune(w, c); + c = peekc(); + } if(lexer.haddollar ? !isidentchar(c) : !iswordchar(c)) break; advance(); diff --git a/src/cmd/rc/main.c b/src/cmd/rc/main.c index 2c0aa42..eb83c90 100644 --- a/src/cmd/rc/main.c +++ b/src/cmd/rc/main.c @@ -54,13 +54,14 @@ main(int argc, char *argv[]) { shell.err = openfd(2); + /* yydebug=1; */ initenv(); initpath(); initkeywords(); initshell(); inithistory(); - enablevi(); + /* enablevi(); */ xboot(argc, argv); /* unreachable */ } diff --git a/src/cmd/rc/parse.c b/src/cmd/rc/parse.c index 1b29d41..c16a578 100644 --- a/src/cmd/rc/parse.c +++ b/src/cmd/rc/parse.c @@ -1,4 +1,4 @@ -/* A Bison parser, made by GNU Bison 3.8.2. */ +/* A Bison parser, made by GNU Bison 3.7.6. */ /* Bison implementation for Yacc-like parsers in C @@ -46,10 +46,10 @@ USER NAME SPACE" below. */ /* Identify Bison output, and Bison version. */ -#define YYBISON 30802 +#define YYBISON 30706 /* Bison version string. */ -#define YYBISON_VERSION "3.8.2" +#define YYBISON_VERSION "3.7.6" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -67,14 +67,14 @@ /* First part of user prologue. */ -#line 7 "sys/cmd/rc/syntax.y" +#line 7 "src/cmd/rc/syntax.y" #include "rc.h" int yylex(void); void yyerror(const char *); -#line 78 "sys/cmd/rc/parse.c" +#line 78 "src/cmd/rc/parse.c" # ifndef YY_CAST # ifdef __cplusplus @@ -323,18 +323,12 @@ typedef int yy_state_fast_t; # define YY_USE(E) /* empty */ #endif +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ -#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ -# if __GNUC__ * 100 + __GNUC_MINOR__ < 407 -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") -# else -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# endif # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else @@ -493,14 +487,14 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 56 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 478 +#define YYLAST 442 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 40 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 24 /* YYNRULES -- Number of rules. */ -#define YYNRULES 73 +#define YYNRULES 71 /* YYNSTATES -- Number of states. */ #define YYNSTATES 129 @@ -551,17 +545,17 @@ static const yytype_int8 yytranslate[] = }; #if YYDEBUG -/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { 0, 38, 38, 39, 42, 43, 46, 47, 50, 53, - 56, 57, 60, 61, 64, 65, 68, 69, 72, 73, - 74, 77, 80, 81, 84, 85, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 105, 106, 107, 110, 111, 114, 115, 118, 119, - 122, 123, 124, 125, 126, 127, 128, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 135, 136, 139, - 140, 141, 143, 145 + 56, 57, 60, 61, 64, 65, 68, 71, 72, 75, + 78, 79, 82, 83, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 103, + 104, 105, 108, 109, 112, 113, 116, 117, 120, 121, + 122, 123, 124, 125, 126, 130, 130, 130, 130, 130, + 130, 130, 130, 130, 130, 133, 134, 137, 138, 139, + 141, 143 }; #endif @@ -595,7 +589,19 @@ yysymbol_name (yysymbol_kind_t yysymbol) } #endif -#define YYPACT_NINF (-82) +#ifdef YYPRINT +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ +static const yytype_int16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 41, 280, 281, 10, 94, + 36, 282, 283, 40, 123, 125, 59, 38, 61, 96 +}; +#endif + +#define YYPACT_NINF (-91) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) @@ -605,170 +611,164 @@ yysymbol_name (yysymbol_kind_t yysymbol) #define yytable_value_is_error(Yyn) \ 0 -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ static const yytype_int16 yypact[] = { - 121, -17, -2, -2, 5, 439, 439, 343, -82, -82, - 343, 343, 343, -82, 439, -23, 45, 32, 11, 439, - 439, 439, 13, 158, -14, -82, 343, 439, -82, -82, - 343, 30, 30, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, 34, -82, -82, 47, -82, -82, - 195, 41, -82, 439, 54, -82, -82, -82, 11, -82, - -82, 30, 30, -82, -82, -82, -82, -82, -82, 34, - 343, 343, 19, 44, 375, 375, 4, 343, -82, -82, - -82, 34, -82, -82, -82, -82, 375, 375, 375, -82, - 34, -82, -82, -82, -82, 29, 77, -82, 29, -82, - -82, 269, -82, 30, 30, 306, 375, -82, 25, -82, - 34, -82, 29, 375, 407, 375, 29, -82, 407, 407, - 48, 54, 29, 232, -82, -82, -82, -82, -82 + 117, -22, -10, -10, 22, 403, 403, 339, -91, -91, + 339, 339, 339, -91, 403, -24, 39, 40, 43, 403, + 403, 403, 72, 154, -5, -91, 339, 403, -91, -91, + 339, 45, 45, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, 38, -91, -91, 51, -91, -91, + 191, 35, -91, 403, 9, -91, -91, -91, 43, -91, + -91, 45, 45, -91, -91, -91, -91, -91, -91, 38, + 339, 339, 18, 46, 371, 371, 19, 339, -91, -91, + -91, 38, -91, -91, -91, -91, 371, 371, 371, -91, + 38, -91, -91, -91, -91, 14, 49, -91, 14, -91, + -91, 228, -91, 45, 45, 265, 371, -91, 32, -91, + 38, -91, 14, 371, -91, 371, 14, -1, 14, -91, + 68, 47, 302, -91, -91, -91, 371, -91, 9 }; -/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ static const yytype_int8 yydefact[] = { - 26, 0, 0, 0, 0, 26, 26, 0, 22, 50, - 0, 0, 0, 69, 26, 0, 0, 0, 24, 26, - 26, 26, 4, 27, 41, 48, 0, 26, 72, 72, - 0, 34, 35, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 46, 23, 44, 45, 51, 54, 55, - 0, 0, 12, 26, 6, 56, 1, 3, 24, 28, - 5, 33, 32, 72, 72, 72, 10, 11, 43, 42, - 0, 0, 0, 0, 26, 26, 0, 0, 67, 53, - 70, 71, 9, 7, 13, 25, 26, 26, 26, 49, - 21, 67, 72, 8, 73, 38, 24, 39, 14, 72, - 47, 0, 29, 30, 31, 0, 26, 72, 0, 52, - 68, 72, 36, 26, 26, 26, 15, 67, 26, 26, - 0, 18, 37, 0, 20, 19, 40, 17, 16 + 24, 0, 0, 0, 0, 24, 24, 0, 20, 48, + 0, 0, 0, 67, 24, 0, 0, 0, 22, 24, + 24, 24, 4, 25, 39, 46, 0, 24, 70, 70, + 0, 32, 33, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 44, 21, 42, 43, 49, 52, 53, + 0, 0, 12, 24, 6, 54, 1, 3, 22, 26, + 5, 31, 30, 70, 70, 70, 10, 11, 41, 40, + 0, 0, 0, 0, 24, 24, 0, 0, 65, 51, + 68, 69, 9, 7, 13, 23, 24, 24, 24, 47, + 19, 65, 70, 8, 71, 36, 22, 37, 14, 70, + 45, 0, 27, 28, 29, 0, 24, 70, 0, 50, + 66, 70, 34, 24, 70, 24, 15, 17, 35, 65, + 17, 0, 0, 18, 38, 70, 24, 16, 0 }; -/* YYPGOTO[NTERM-NUM]. */ + /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -82, -82, 75, -19, 93, -11, 18, -52, -82, -82, - -21, -82, -1, 42, 0, -82, -9, 28, -82, 2, - -82, -81, -82, -22 + -91, -91, 65, -23, 87, -12, 34, -35, -91, -91, + -28, -91, -16, 36, 0, -91, 6, 31, -91, 2, + -91, -90, -91, -14 }; -/* YYDEFGOTO[NTERM-NUM]. */ + /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - 0, 16, 17, 51, 28, 18, 52, 53, 97, 119, - 120, 20, 21, 59, 54, 23, 43, 110, 24, 25, + 0, 16, 17, 51, 28, 18, 52, 53, 97, 120, + 121, 20, 21, 59, 54, 23, 43, 110, 24, 25, 46, 101, 50, 74 }; -/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 22, 47, 48, 49, 55, 31, 32, 75, 73, 45, - 105, 14, 45, 45, 45, 70, 26, 58, 19, 22, - 61, 62, 68, 91, 71, 45, 7, 8, 45, 99, - 63, 27, 45, 77, 83, 44, 123, 19, 30, 64, - 65, 86, 87, 88, 92, 56, 63, 63, 77, 66, - 67, 69, 45, 94, 72, 64, 65, 58, 76, 114, - 57, 89, 118, 77, 96, 78, 118, 118, 100, 93, - 106, 63, 45, 45, 95, 98, 82, 108, 81, 45, - 64, 65, 84, 126, 107, 113, 102, 103, 104, 115, - 66, 67, 7, 8, 60, 58, 29, 124, 125, 90, - 85, 0, 0, 45, 0, 0, 112, 45, 0, 0, - 0, 0, 0, 116, 121, 122, 0, 0, 121, 121, - 0, -2, 0, 0, 1, 45, 2, 3, 0, 4, - 0, 0, 0, 5, 6, 0, 7, 8, 0, 0, - 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 10, 11, 12, 13, 14, 0, 0, 0, 0, + 22, 105, 58, 55, 73, 31, 32, 68, 119, 45, + 14, 26, 45, 45, 45, 75, 47, 48, 49, 22, + 61, 62, 91, 27, 70, 45, 63, 94, 45, 122, + 83, 63, 45, 71, 19, 64, 65, 84, 44, 56, + 64, 65, 58, 92, 99, 66, 67, 77, 77, 86, + 87, 88, 45, 19, 69, 30, 107, 72, 7, 8, + 94, 76, 63, 96, 7, 8, 114, 77, 57, 78, + 82, 93, 45, 45, 95, 98, 89, 119, 106, 45, + 58, 81, 124, 100, 60, 108, 102, 103, 104, 63, + 29, 127, 123, 113, 85, 0, 0, 115, 64, 65, + 117, 0, 90, 45, 0, 0, 112, 45, 66, 67, + 0, 126, 0, 116, 0, 118, 0, -2, 0, 0, + 1, 0, 2, 3, 45, 4, 128, 0, 0, 5, + 6, 0, 7, 8, 0, 0, 0, 0, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, + 13, 14, 0, 0, 0, 0, 15, 33, 34, 35, + 36, 37, 38, 39, 0, 0, 40, 41, 42, 7, + 8, 0, 0, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 10, 11, 12, 13, 0, 0, + 0, 0, 0, 15, 33, 34, 35, 36, 37, 38, + 39, 0, 0, 40, 41, 42, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 79, 0, 0, 80, + 0, 10, 11, 12, 13, 0, 0, 0, 0, 0, 15, 33, 34, 35, 36, 37, 38, 39, 0, 0, - 40, 41, 42, 7, 8, 0, 0, 0, 0, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, + 40, 41, 42, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 109, 0, 0, 0, 0, 10, 11, 12, 13, 0, 0, 0, 0, 0, 15, 33, 34, 35, 36, 37, 38, 39, 0, 0, 40, 41, 42, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, - 79, 0, 0, 80, 0, 10, 11, 12, 13, 0, + 111, 0, 0, 0, 0, 10, 11, 12, 13, 0, 0, 0, 0, 0, 15, 33, 34, 35, 36, 37, 38, 39, 0, 0, 40, 41, 42, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, - 127, 0, 10, 11, 12, 13, 0, 0, 128, 0, + 0, 0, 10, 11, 12, 13, 0, 0, 125, 0, 0, 15, 33, 34, 35, 36, 37, 38, 39, 0, 0, 40, 41, 42, 0, 0, 0, 0, 0, 0, - 9, 0, 0, 0, 109, 0, 0, 0, 0, 10, - 11, 12, 13, 0, 0, 0, 0, 0, 15, 33, - 34, 35, 36, 37, 38, 39, 0, 0, 40, 41, - 42, 0, 0, 0, 0, 0, 0, 9, 0, 0, - 0, 111, 0, 0, 0, 0, 10, 11, 12, 13, - 0, 0, 0, 0, 0, 15, 33, 34, 35, 36, - 37, 38, 39, 0, 0, 40, 41, 42, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 10, 11, 12, 13, 0, 1, 0, - 2, 3, 15, 4, 0, 0, 0, 5, 6, 0, - 7, 8, 0, 0, 0, 0, 9, 0, 0, 0, - 0, 0, 0, 94, 0, 10, 11, 12, 13, 14, - 1, 0, 2, 3, 15, 4, 117, 0, 0, 5, - 6, 0, 7, 8, 0, 0, 0, 0, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, - 13, 14, 1, 0, 2, 3, 15, 4, 0, 0, - 0, 5, 6, 0, 7, 8, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 10, - 11, 12, 13, 14, 0, 0, 0, 0, 15 + 11, 12, 13, 0, 1, 0, 2, 3, 15, 4, + 0, 0, 0, 5, 6, 0, 7, 8, 0, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 94, + 0, 10, 11, 12, 13, 14, 1, 0, 2, 3, + 15, 4, 0, 0, 0, 5, 6, 0, 7, 8, + 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 11, 12, 13, 14, 0, 0, + 0, 0, 15 }; static const yytype_int8 yycheck[] = { - 0, 10, 11, 12, 15, 5, 6, 29, 27, 7, - 91, 34, 10, 11, 12, 29, 33, 18, 0, 19, - 20, 21, 23, 4, 38, 23, 15, 16, 26, 25, - 17, 33, 30, 29, 53, 7, 117, 19, 33, 26, - 27, 63, 64, 65, 25, 0, 17, 17, 29, 36, - 37, 23, 50, 28, 26, 26, 27, 58, 30, 34, - 28, 70, 114, 29, 75, 18, 118, 119, 77, 25, - 92, 17, 70, 71, 74, 75, 35, 99, 50, 77, - 26, 27, 28, 35, 7, 107, 86, 87, 88, 111, - 36, 37, 15, 16, 19, 96, 3, 118, 119, 71, - 58, -1, -1, 101, -1, -1, 106, 105, -1, -1, - -1, -1, -1, 113, 114, 115, -1, -1, 118, 119, - -1, 0, -1, -1, 3, 123, 5, 6, -1, 8, - -1, -1, -1, 12, 13, -1, 15, 16, -1, -1, - -1, -1, 21, -1, -1, -1, -1, -1, -1, -1, - -1, 30, 31, 32, 33, 34, -1, -1, -1, -1, + 0, 91, 18, 15, 27, 5, 6, 23, 9, 7, + 34, 33, 10, 11, 12, 29, 10, 11, 12, 19, + 20, 21, 4, 33, 29, 23, 17, 28, 26, 119, + 53, 17, 30, 38, 0, 26, 27, 28, 7, 0, + 26, 27, 58, 25, 25, 36, 37, 29, 29, 63, + 64, 65, 50, 19, 23, 33, 7, 26, 15, 16, + 28, 30, 17, 75, 15, 16, 34, 29, 28, 18, + 35, 25, 70, 71, 74, 75, 70, 9, 92, 77, + 96, 50, 35, 77, 19, 99, 86, 87, 88, 17, + 3, 126, 120, 107, 58, -1, -1, 111, 26, 27, + 114, -1, 71, 101, -1, -1, 106, 105, 36, 37, + -1, 125, -1, 113, -1, 115, -1, 0, -1, -1, + 3, -1, 5, 6, 122, 8, 126, -1, -1, 12, + 13, -1, 15, 16, -1, -1, -1, -1, 21, -1, + -1, -1, -1, -1, -1, -1, -1, 30, 31, 32, + 33, 34, -1, -1, -1, -1, 39, 3, 4, 5, + 6, 7, 8, 9, -1, -1, 12, 13, 14, 15, + 16, -1, -1, -1, -1, 21, -1, -1, -1, -1, + -1, -1, -1, -1, 30, 31, 32, 33, -1, -1, + -1, -1, -1, 39, 3, 4, 5, 6, 7, 8, + 9, -1, -1, 12, 13, 14, -1, -1, -1, -1, + -1, -1, 21, -1, -1, -1, 25, -1, -1, 28, + -1, 30, 31, 32, 33, -1, -1, -1, -1, -1, 39, 3, 4, 5, 6, 7, 8, 9, -1, -1, - 12, 13, 14, 15, 16, -1, -1, -1, -1, 21, - -1, -1, -1, -1, -1, -1, -1, -1, 30, 31, + 12, 13, 14, -1, -1, -1, -1, -1, -1, 21, + -1, -1, -1, 25, -1, -1, -1, -1, 30, 31, 32, 33, -1, -1, -1, -1, -1, 39, 3, 4, 5, 6, 7, 8, 9, -1, -1, 12, 13, 14, -1, -1, -1, -1, -1, -1, 21, -1, -1, -1, - 25, -1, -1, 28, -1, 30, 31, 32, 33, -1, + 25, -1, -1, -1, -1, 30, 31, 32, 33, -1, -1, -1, -1, -1, 39, 3, 4, 5, 6, 7, 8, 9, -1, -1, 12, 13, 14, -1, -1, -1, -1, -1, -1, 21, -1, -1, -1, -1, -1, -1, - 28, -1, 30, 31, 32, 33, -1, -1, 36, -1, + -1, -1, 30, 31, 32, 33, -1, -1, 36, -1, -1, 39, 3, 4, 5, 6, 7, 8, 9, -1, -1, 12, 13, 14, -1, -1, -1, -1, -1, -1, - 21, -1, -1, -1, 25, -1, -1, -1, -1, 30, - 31, 32, 33, -1, -1, -1, -1, -1, 39, 3, - 4, 5, 6, 7, 8, 9, -1, -1, 12, 13, - 14, -1, -1, -1, -1, -1, -1, 21, -1, -1, - -1, 25, -1, -1, -1, -1, 30, 31, 32, 33, - -1, -1, -1, -1, -1, 39, 3, 4, 5, 6, - 7, 8, 9, -1, -1, 12, 13, 14, -1, -1, - -1, -1, -1, -1, 21, -1, -1, -1, -1, -1, - -1, -1, -1, 30, 31, 32, 33, -1, 3, -1, - 5, 6, 39, 8, -1, -1, -1, 12, 13, -1, - 15, 16, -1, -1, -1, -1, 21, -1, -1, -1, - -1, -1, -1, 28, -1, 30, 31, 32, 33, 34, - 3, -1, 5, 6, 39, 8, 9, -1, -1, 12, - 13, -1, 15, 16, -1, -1, -1, -1, 21, -1, - -1, -1, -1, -1, -1, -1, -1, 30, 31, 32, - 33, 34, 3, -1, 5, 6, 39, 8, -1, -1, - -1, 12, 13, -1, 15, 16, -1, -1, -1, -1, 21, -1, -1, -1, -1, -1, -1, -1, -1, 30, - 31, 32, 33, 34, -1, -1, -1, -1, 39 + 31, 32, 33, -1, 3, -1, 5, 6, 39, 8, + -1, -1, -1, 12, 13, -1, 15, 16, -1, -1, + -1, -1, 21, -1, -1, -1, -1, -1, -1, 28, + -1, 30, 31, 32, 33, 34, 3, -1, 5, 6, + 39, 8, -1, -1, -1, 12, 13, -1, 15, 16, + -1, -1, -1, -1, 21, -1, -1, -1, -1, -1, + -1, -1, -1, 30, 31, 32, 33, 34, -1, -1, + -1, -1, 39 }; -/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of - state STATE-NUM. */ + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ static const yytype_int8 yystos[] = { 0, 3, 5, 6, 8, 12, 13, 15, 16, 21, @@ -782,34 +782,34 @@ static const yytype_int8 yystos[] = 28, 57, 35, 43, 28, 53, 63, 63, 63, 56, 57, 4, 25, 25, 28, 54, 45, 48, 54, 25, 56, 61, 54, 54, 54, 61, 63, 7, 63, 25, - 57, 25, 54, 63, 34, 63, 54, 9, 47, 49, - 50, 54, 54, 61, 50, 50, 35, 28, 36 + 57, 25, 54, 63, 34, 63, 54, 63, 54, 9, + 49, 50, 61, 50, 35, 36, 63, 47, 54 }; -/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_int8 yyr1[] = { 0, 40, 41, 41, 42, 42, 43, 43, 44, 45, - 46, 46, 47, 47, 48, 48, 49, 49, 50, 50, - 50, 51, 52, 52, 53, 53, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 55, 55, 55, 56, 56, 57, 57, 58, 58, - 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 61, 61, 62, - 62, 62, 63, 63 + 46, 46, 47, 47, 48, 48, 49, 50, 50, 51, + 52, 52, 53, 53, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, + 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, + 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 61, 61, 62, 62, 62, + 63, 63 }; -/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_int8 yyr2[] = { 0, 2, 0, 2, 1, 2, 1, 2, 3, 3, - 2, 2, 1, 2, 1, 4, 3, 3, 1, 2, - 2, 3, 1, 2, 0, 2, 0, 1, 2, 4, - 4, 4, 2, 2, 2, 2, 6, 8, 4, 4, - 8, 1, 2, 2, 1, 1, 1, 3, 1, 3, - 1, 2, 5, 3, 2, 2, 2, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, - 2, 2, 0, 2 + 2, 2, 1, 2, 1, 4, 5, 0, 2, 3, + 1, 2, 0, 2, 0, 1, 2, 4, 4, 4, + 2, 2, 2, 2, 6, 8, 4, 4, 9, 1, + 2, 2, 1, 1, 1, 3, 1, 3, 1, 2, + 5, 3, 2, 2, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 2, 0, 2, 2, + 0, 2 }; @@ -821,7 +821,6 @@ enum { YYENOMEM = -2 }; #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab -#define YYNOMEM goto yyexhaustedlab #define YYRECOVERING() (!!yyerrstatus) @@ -862,7 +861,10 @@ do { \ YYFPRINTF Args; \ } while (0) - +/* This macro is provided for backward compatibility. */ +# ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif # define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ @@ -889,6 +891,10 @@ yy_symbol_value_print (FILE *yyo, YY_USE (yyoutput); if (!yyvaluep) return; +# ifdef YYPRINT + if (yykind < YYNTOKENS) + YYPRINT (yyo, yytoknum[yykind], *yyvaluep); +# endif YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END @@ -1343,7 +1349,6 @@ yyparse (void) YYDPRINTF ((stderr, "Starting parse\n")); yychar = YYEMPTY; /* Cause a token to be read. */ - goto yysetstate; @@ -1369,7 +1374,7 @@ yysetstate: if (yyss + yystacksize - 1 <= yyssp) #if !defined yyoverflow && !defined YYSTACK_RELOCATE - YYNOMEM; + goto yyexhaustedlab; #else { /* Get the current used size of the three stacks, in elements. */ @@ -1397,7 +1402,7 @@ yysetstate: # else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - YYNOMEM; + goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; @@ -1408,7 +1413,7 @@ yysetstate: YY_CAST (union yyalloc *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); if (! yyptr) - YYNOMEM; + goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE @@ -1430,7 +1435,6 @@ yysetstate: } #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ - if (yystate == YYFINAL) YYACCEPT; @@ -1543,295 +1547,283 @@ yyreduce: switch (yyn) { case 2: /* rc: %empty */ -#line 38 "sys/cmd/rc/syntax.y" +#line 38 "src/cmd/rc/syntax.y" { return 0; } -#line 1549 "sys/cmd/rc/parse.c" +#line 1553 "src/cmd/rc/parse.c" break; case 3: /* rc: line '\n' */ -#line 39 "sys/cmd/rc/syntax.y" +#line 39 "src/cmd/rc/syntax.y" { return compile((yyvsp[-1].tree)); } -#line 1555 "sys/cmd/rc/parse.c" +#line 1559 "src/cmd/rc/parse.c" break; case 5: /* line: cmds line */ -#line 43 "sys/cmd/rc/syntax.y" +#line 43 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree2(';', (yyvsp[-1].tree), (yyvsp[0].tree)); } -#line 1561 "sys/cmd/rc/parse.c" +#line 1565 "src/cmd/rc/parse.c" break; case 7: /* body: cmdsln body */ -#line 47 "sys/cmd/rc/syntax.y" +#line 47 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree2(';', (yyvsp[-1].tree), (yyvsp[0].tree)); } -#line 1567 "sys/cmd/rc/parse.c" +#line 1571 "src/cmd/rc/parse.c" break; case 8: /* paren: '(' body ')' */ -#line 50 "sys/cmd/rc/syntax.y" +#line 50 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree1(Tparen, (yyvsp[-1].tree)); } -#line 1573 "sys/cmd/rc/parse.c" +#line 1577 "src/cmd/rc/parse.c" break; case 9: /* block: '{' body '}' */ -#line 53 "sys/cmd/rc/syntax.y" +#line 53 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree1(Tblock, (yyvsp[-1].tree)); } -#line 1579 "sys/cmd/rc/parse.c" +#line 1583 "src/cmd/rc/parse.c" break; case 11: /* cmds: cmd '&' */ -#line 57 "sys/cmd/rc/syntax.y" +#line 57 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree1('&', (yyvsp[-1].tree)); } -#line 1585 "sys/cmd/rc/parse.c" +#line 1589 "src/cmd/rc/parse.c" break; case 14: /* ifbody: cmd */ -#line 64 "sys/cmd/rc/syntax.y" +#line 64 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree2(Tif, nil, (yyvsp[0].tree)); } -#line 1591 "sys/cmd/rc/parse.c" +#line 1595 "src/cmd/rc/parse.c" break; case 15: /* ifbody: block Telse nl cmd */ -#line 65 "sys/cmd/rc/syntax.y" +#line 65 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree3(Tif, nil, (yyvsp[-3].tree), (yyvsp[-2].tree)); } -#line 1597 "sys/cmd/rc/parse.c" +#line 1601 "src/cmd/rc/parse.c" break; - case 16: /* case: Tcase words ';' */ -#line 68 "sys/cmd/rc/syntax.y" - { (yyval.tree) = hangchild1((yyvsp[-2].tree), (yyvsp[-1].tree), 0); } -#line 1603 "sys/cmd/rc/parse.c" + case 16: /* case: Tcase words ';' nl cmdsln */ +#line 68 "src/cmd/rc/syntax.y" + { (yyval.tree) = hangchild2((yyvsp[-4].tree), (yyvsp[-3].tree), 0, (yyvsp[0].tree), 1);} +#line 1607 "src/cmd/rc/parse.c" break; - case 17: /* case: Tcase words '\n' */ -#line 69 "sys/cmd/rc/syntax.y" - { (yyval.tree) = hangchild1((yyvsp[-2].tree), (yyvsp[-1].tree), 0); } -#line 1609 "sys/cmd/rc/parse.c" - break; - - case 18: /* casebody: cmd */ -#line 72 "sys/cmd/rc/syntax.y" - { (yyval.tree) = maketree2(Tcasebody, (yyvsp[0].tree), nil); } -#line 1615 "sys/cmd/rc/parse.c" - break; - - case 19: /* casebody: case casebody */ -#line 73 "sys/cmd/rc/syntax.y" - { (yyval.tree) = maketree2(Tcasebody, (yyvsp[-1].tree), (yyvsp[0].tree)); } -#line 1621 "sys/cmd/rc/parse.c" + case 17: /* casebody: %empty */ +#line 71 "src/cmd/rc/syntax.y" + { (yyval.tree) = nil; } +#line 1613 "src/cmd/rc/parse.c" break; - case 20: /* casebody: cmdsln casebody */ -#line 74 "sys/cmd/rc/syntax.y" - { (yyval.tree) = maketree2(Tcasebody, (yyvsp[-1].tree), (yyvsp[0].tree)); } -#line 1627 "sys/cmd/rc/parse.c" + case 18: /* casebody: case casebody */ +#line 72 "src/cmd/rc/syntax.y" + { (yyval.tree) = (!(yyvsp[0].tree)) ? (yyvsp[-1].tree) : maketree2(';', (yyvsp[-1].tree), (yyvsp[0].tree)); } +#line 1619 "src/cmd/rc/parse.c" break; - case 21: /* assign: executable '=' word */ -#line 77 "sys/cmd/rc/syntax.y" + case 19: /* assign: executable '=' word */ +#line 75 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree2('=', (yyvsp[-2].tree), (yyvsp[0].tree)); } -#line 1633 "sys/cmd/rc/parse.c" +#line 1625 "src/cmd/rc/parse.c" break; - case 23: /* redir: Tredir word */ -#line 81 "sys/cmd/rc/syntax.y" + case 21: /* redir: Tredir word */ +#line 79 "src/cmd/rc/syntax.y" { (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 0); } -#line 1639 "sys/cmd/rc/parse.c" +#line 1631 "src/cmd/rc/parse.c" break; - case 24: /* epilog: %empty */ -#line 84 "sys/cmd/rc/syntax.y" + case 22: /* epilog: %empty */ +#line 82 "src/cmd/rc/syntax.y" { (yyval.tree) = nil; } -#line 1645 "sys/cmd/rc/parse.c" +#line 1637 "src/cmd/rc/parse.c" break; - case 25: /* epilog: redir epilog */ -#line 85 "sys/cmd/rc/syntax.y" + case 23: /* epilog: redir epilog */ +#line 83 "src/cmd/rc/syntax.y" { (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 1); } -#line 1651 "sys/cmd/rc/parse.c" +#line 1643 "src/cmd/rc/parse.c" break; - case 26: /* cmd: %empty */ -#line 88 "sys/cmd/rc/syntax.y" - { (yyval.tree) = nil; } -#line 1657 "sys/cmd/rc/parse.c" + case 24: /* cmd: %empty */ +#line 86 "src/cmd/rc/syntax.y" + { (yyval.tree) = nil; } +#line 1649 "src/cmd/rc/parse.c" break; - case 27: /* cmd: basic */ -#line 89 "sys/cmd/rc/syntax.y" - { (yyval.tree) = maketree1(Tbasic, (yyvsp[0].tree)); } -#line 1663 "sys/cmd/rc/parse.c" + case 25: /* cmd: basic */ +#line 87 "src/cmd/rc/syntax.y" + { (yyval.tree) = maketree1(Tbasic, (yyvsp[0].tree)); } +#line 1655 "src/cmd/rc/parse.c" break; - case 28: /* cmd: block epilog */ -#line 90 "sys/cmd/rc/syntax.y" - { (yyval.tree) = hangepilog((yyvsp[-1].tree), (yyvsp[0].tree)); } -#line 1669 "sys/cmd/rc/parse.c" + case 26: /* cmd: block epilog */ +#line 88 "src/cmd/rc/syntax.y" + { (yyval.tree) = hangepilog((yyvsp[-1].tree), (yyvsp[0].tree)); } +#line 1661 "src/cmd/rc/parse.c" break; - case 29: /* cmd: cmd Tpipe nl cmd */ -#line 91 "sys/cmd/rc/syntax.y" - { (yyval.tree) = hangchild2((yyvsp[-2].tree), (yyvsp[-3].tree), 0, (yyvsp[0].tree), 1); } -#line 1675 "sys/cmd/rc/parse.c" + case 27: /* cmd: cmd Tpipe nl cmd */ +#line 89 "src/cmd/rc/syntax.y" + { (yyval.tree) = hangchild2((yyvsp[-2].tree), (yyvsp[-3].tree), 0, (yyvsp[0].tree), 1); } +#line 1667 "src/cmd/rc/parse.c" break; - case 30: /* cmd: cmd Tandand nl cmd */ -#line 92 "sys/cmd/rc/syntax.y" - { (yyval.tree) = maketree2(Tandand, (yyvsp[-3].tree), (yyvsp[0].tree)); } -#line 1681 "sys/cmd/rc/parse.c" + case 28: /* cmd: cmd Tandand nl cmd */ +#line 90 "src/cmd/rc/syntax.y" + { (yyval.tree) = maketree2(Tandand, (yyvsp[-3].tree), (yyvsp[0].tree)); } +#line 1673 "src/cmd/rc/parse.c" break; - case 31: /* cmd: cmd Toror nl cmd */ -#line 93 "sys/cmd/rc/syntax.y" - { (yyval.tree) = maketree2(Toror, (yyvsp[-3].tree), (yyvsp[0].tree)); } -#line 1687 "sys/cmd/rc/parse.c" + case 29: /* cmd: cmd Toror nl cmd */ +#line 91 "src/cmd/rc/syntax.y" + { (yyval.tree) = maketree2(Toror, (yyvsp[-3].tree), (yyvsp[0].tree)); } +#line 1679 "src/cmd/rc/parse.c" break; - case 32: /* cmd: redir cmd */ -#line 94 "sys/cmd/rc/syntax.y" - { (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 1); } -#line 1693 "sys/cmd/rc/parse.c" + case 30: /* cmd: redir cmd */ +#line 92 "src/cmd/rc/syntax.y" + { (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 1); } +#line 1685 "src/cmd/rc/parse.c" break; - case 33: /* cmd: assign cmd */ -#line 95 "sys/cmd/rc/syntax.y" - { (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 2); } -#line 1699 "sys/cmd/rc/parse.c" + case 31: /* cmd: assign cmd */ +#line 93 "src/cmd/rc/syntax.y" + { (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 2); } +#line 1691 "src/cmd/rc/parse.c" break; - case 34: /* cmd: Tbang cmd */ -#line 96 "sys/cmd/rc/syntax.y" - { (yyval.tree) = maketree1(Tbang, (yyvsp[0].tree)); } -#line 1705 "sys/cmd/rc/parse.c" + case 32: /* cmd: Tbang cmd */ +#line 94 "src/cmd/rc/syntax.y" + { (yyval.tree) = maketree1(Tbang, (yyvsp[0].tree)); } +#line 1697 "src/cmd/rc/parse.c" break; - case 35: /* cmd: Tsubshell cmd */ -#line 97 "sys/cmd/rc/syntax.y" - { (yyval.tree) = maketree1(Tsubshell, (yyvsp[0].tree)); } -#line 1711 "sys/cmd/rc/parse.c" + case 33: /* cmd: Tsubshell cmd */ +#line 95 "src/cmd/rc/syntax.y" + { (yyval.tree) = maketree1(Tsubshell, (yyvsp[0].tree)); } +#line 1703 "src/cmd/rc/parse.c" break; - case 36: /* cmd: Tfor '(' word ')' nl cmd */ -#line 98 "sys/cmd/rc/syntax.y" - { (yyval.tree) = hangchild3((yyvsp[-5].tree), (yyvsp[-3].tree), nil, (yyvsp[0].tree)); } -#line 1717 "sys/cmd/rc/parse.c" + case 34: /* cmd: Tfor '(' word ')' nl cmd */ +#line 96 "src/cmd/rc/syntax.y" + { (yyval.tree) = hangchild3((yyvsp[-5].tree), (yyvsp[-3].tree), nil, (yyvsp[0].tree)); } +#line 1709 "src/cmd/rc/parse.c" break; - case 37: /* cmd: Tfor '(' word Tin words ')' nl cmd */ -#line 99 "sys/cmd/rc/syntax.y" - { (yyval.tree) = hangchild3((yyvsp[-7].tree), (yyvsp[-5].tree), (yyvsp[-3].tree), (yyvsp[0].tree)); } -#line 1723 "sys/cmd/rc/parse.c" + case 35: /* cmd: Tfor '(' word Tin words ')' nl cmd */ +#line 97 "src/cmd/rc/syntax.y" + { (yyval.tree) = hangchild3((yyvsp[-7].tree), (yyvsp[-5].tree), (yyvsp[-3].tree), (yyvsp[0].tree)); } +#line 1715 "src/cmd/rc/parse.c" break; - case 38: /* cmd: Twhile paren nl cmd */ -#line 100 "sys/cmd/rc/syntax.y" - { (yyval.tree) = hangchild2((yyvsp[-3].tree), (yyvsp[-2].tree), 0, (yyvsp[0].tree), 1); } -#line 1729 "sys/cmd/rc/parse.c" + case 36: /* cmd: Twhile paren nl cmd */ +#line 98 "src/cmd/rc/syntax.y" + { (yyval.tree) = hangchild2((yyvsp[-3].tree), (yyvsp[-2].tree), 0, (yyvsp[0].tree), 1); } +#line 1721 "src/cmd/rc/parse.c" break; - case 39: /* cmd: Tif paren nl ifbody */ -#line 101 "sys/cmd/rc/syntax.y" - { (yyval.tree) = hangchild1((yyvsp[-2].tree), (yyvsp[-3].tree), 0); } -#line 1735 "sys/cmd/rc/parse.c" + case 37: /* cmd: Tif paren nl ifbody */ +#line 99 "src/cmd/rc/syntax.y" + { (yyval.tree) = hangchild1((yyvsp[-2].tree), (yyvsp[-2].tree), 0); } +#line 1727 "src/cmd/rc/parse.c" break; - case 40: /* cmd: Tswitch '(' word ')' nl '{' casebody '}' */ -#line 102 "sys/cmd/rc/syntax.y" - { (yyval.tree) = hangchild2((yyvsp[-7].tree), (yyvsp[-5].tree), 0, (yyvsp[-1].tree), 1); } -#line 1741 "sys/cmd/rc/parse.c" + case 38: /* cmd: Tswitch '(' word ')' nl '{' nl casebody '}' */ +#line 100 "src/cmd/rc/syntax.y" + { (yyval.tree) = hangchild2((yyvsp[-8].tree), (yyvsp[-6].tree), 0, (yyvsp[-1].tree), 1); } +#line 1733 "src/cmd/rc/parse.c" break; - case 42: /* basic: basic word */ -#line 106 "sys/cmd/rc/syntax.y" + case 40: /* basic: basic word */ +#line 104 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree2(Targs, (yyvsp[-1].tree), (yyvsp[0].tree)); } -#line 1747 "sys/cmd/rc/parse.c" +#line 1739 "src/cmd/rc/parse.c" break; - case 43: /* basic: basic redir */ -#line 107 "sys/cmd/rc/syntax.y" + case 41: /* basic: basic redir */ +#line 105 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree2(Targs, (yyvsp[-1].tree), (yyvsp[0].tree)); } -#line 1753 "sys/cmd/rc/parse.c" +#line 1745 "src/cmd/rc/parse.c" break; - case 45: /* atom: keyword */ -#line 111 "sys/cmd/rc/syntax.y" + case 43: /* atom: keyword */ +#line 109 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree1(Tword, (yyvsp[0].tree)); } -#line 1759 "sys/cmd/rc/parse.c" +#line 1751 "src/cmd/rc/parse.c" break; - case 47: /* word: word '^' atom */ -#line 115 "sys/cmd/rc/syntax.y" + case 45: /* word: word '^' atom */ +#line 113 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree2('^', (yyvsp[-2].tree), (yyvsp[0].tree)); } -#line 1765 "sys/cmd/rc/parse.c" +#line 1757 "src/cmd/rc/parse.c" break; - case 49: /* executable: executable '^' atom */ -#line 119 "sys/cmd/rc/syntax.y" + case 47: /* executable: executable '^' atom */ +#line 117 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree2('^', (yyvsp[-2].tree), (yyvsp[0].tree)); } -#line 1771 "sys/cmd/rc/parse.c" +#line 1763 "src/cmd/rc/parse.c" break; - case 51: /* nonkeyword: '$' atom */ -#line 123 "sys/cmd/rc/syntax.y" + case 49: /* nonkeyword: '$' atom */ +#line 121 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree1('$', (yyvsp[0].tree)); } -#line 1777 "sys/cmd/rc/parse.c" +#line 1769 "src/cmd/rc/parse.c" break; - case 52: /* nonkeyword: '$' atom Tindex words ')' */ -#line 124 "sys/cmd/rc/syntax.y" + case 50: /* nonkeyword: '$' atom Tindex words ')' */ +#line 122 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree2(Tindex, (yyvsp[-3].tree), (yyvsp[-1].tree)); } -#line 1783 "sys/cmd/rc/parse.c" +#line 1775 "src/cmd/rc/parse.c" break; - case 53: /* nonkeyword: '(' wordsnl ')' */ -#line 125 "sys/cmd/rc/syntax.y" + case 51: /* nonkeyword: '(' wordsnl ')' */ +#line 123 "src/cmd/rc/syntax.y" { (yyval.tree) = (yyvsp[-1].tree); } -#line 1789 "sys/cmd/rc/parse.c" +#line 1781 "src/cmd/rc/parse.c" break; - case 54: /* nonkeyword: Tcount atom */ -#line 126 "sys/cmd/rc/syntax.y" + case 52: /* nonkeyword: Tcount atom */ +#line 124 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree1(Tcount, (yyvsp[0].tree)); } -#line 1795 "sys/cmd/rc/parse.c" +#line 1787 "src/cmd/rc/parse.c" break; - case 55: /* nonkeyword: Tjoin atom */ -#line 127 "sys/cmd/rc/syntax.y" + case 53: /* nonkeyword: Tjoin atom */ +#line 125 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree1(Tjoin, (yyvsp[0].tree)); } -#line 1801 "sys/cmd/rc/parse.c" +#line 1793 "src/cmd/rc/parse.c" break; - case 56: /* nonkeyword: '`' block */ -#line 128 "sys/cmd/rc/syntax.y" + case 54: /* nonkeyword: '`' block */ +#line 126 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree1('`', (yyvsp[0].tree)); } -#line 1807 "sys/cmd/rc/parse.c" +#line 1799 "src/cmd/rc/parse.c" break; - case 67: /* words: %empty */ -#line 135 "sys/cmd/rc/syntax.y" + case 65: /* words: %empty */ +#line 133 "src/cmd/rc/syntax.y" { (yyval.tree) = nil; } -#line 1813 "sys/cmd/rc/parse.c" +#line 1805 "src/cmd/rc/parse.c" break; - case 68: /* words: words word */ -#line 136 "sys/cmd/rc/syntax.y" + case 66: /* words: words word */ +#line 134 "src/cmd/rc/syntax.y" { (yyval.tree) = maketree2(Twords, (yyvsp[-1].tree), (yyvsp[0].tree)); } -#line 1819 "sys/cmd/rc/parse.c" +#line 1811 "src/cmd/rc/parse.c" break; - case 69: /* wordsnl: %empty */ -#line 139 "sys/cmd/rc/syntax.y" + case 67: /* wordsnl: %empty */ +#line 137 "src/cmd/rc/syntax.y" { (yyval.tree) = nil; } -#line 1825 "sys/cmd/rc/parse.c" +#line 1817 "src/cmd/rc/parse.c" break; - case 71: /* wordsnl: wordsnl word */ -#line 141 "sys/cmd/rc/syntax.y" + case 69: /* wordsnl: wordsnl word */ +#line 139 "src/cmd/rc/syntax.y" {(yyval.tree) = (!(yyvsp[-1].tree)) ? ((!(yyvsp[0].tree)) ? nil : (yyvsp[0].tree)) : ((!(yyvsp[0].tree)) ? (yyvsp[-1].tree) : maketree2(Twords, (yyvsp[-1].tree), (yyvsp[0].tree))); } -#line 1831 "sys/cmd/rc/parse.c" +#line 1823 "src/cmd/rc/parse.c" break; -#line 1835 "sys/cmd/rc/parse.c" +#line 1827 "src/cmd/rc/parse.c" default: break; } @@ -1907,7 +1899,7 @@ yyerrlab: } yyerror (yymsgp); if (yysyntax_error_status == YYENOMEM) - YYNOMEM; + goto yyexhaustedlab; } } @@ -1943,7 +1935,6 @@ yyerrorlab: label yyerrorlab therefore never appears in user code. */ if (0) YYERROR; - ++yynerrs; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ @@ -2004,7 +1995,7 @@ yyerrlab1: `-------------------------------------*/ yyacceptlab: yyresult = 0; - goto yyreturnlab; + goto yyreturn; /*-----------------------------------. @@ -2012,22 +2003,24 @@ yyacceptlab: `-----------------------------------*/ yyabortlab: yyresult = 1; - goto yyreturnlab; + goto yyreturn; -/*-----------------------------------------------------------. -| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | -`-----------------------------------------------------------*/ +#if 1 +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; - goto yyreturnlab; + goto yyreturn; +#endif -/*----------------------------------------------------------. -| yyreturnlab -- parsing is finished, clean up and return. | -`----------------------------------------------------------*/ -yyreturnlab: +/*-------------------------------------------------------. +| yyreturn -- parsing is finished, clean up and return. | +`-------------------------------------------------------*/ +yyreturn: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at @@ -2055,5 +2048,5 @@ yyreturnlab: return yyresult; } -#line 147 "sys/cmd/rc/syntax.y" +#line 145 "src/cmd/rc/syntax.y" diff --git a/src/cmd/rc/parse.h b/src/cmd/rc/parse.h index 64ee07b..a99e118 100644 --- a/src/cmd/rc/parse.h +++ b/src/cmd/rc/parse.h @@ -1,4 +1,4 @@ -/* A Bison parser, made by GNU Bison 3.8.2. */ +/* A Bison parser, made by GNU Bison 3.7.6. */ /* Bison interface for Yacc-like parsers in C @@ -35,11 +35,11 @@ especially those whose name start with YY_ or yy_. They are private implementation details that can be changed or removed. */ -#ifndef YY_YY_SYS_CMD_RC_PARSE_H_INCLUDED -# define YY_YY_SYS_CMD_RC_PARSE_H_INCLUDED +#ifndef YY_YY_SRC_CMD_RC_PARSE_H_INCLUDED +# define YY_YY_SRC_CMD_RC_PARSE_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG -# define YYDEBUG 0 +# define YYDEBUG 1 #endif #if YYDEBUG extern int yydebug; @@ -83,47 +83,16 @@ extern int yydebug; }; typedef enum yytokentype yytoken_kind_t; #endif -/* Token kinds. */ -#define YYEMPTY -2 -#define YYEOF 0 -#define YYerror 256 -#define YYUNDEF 257 -#define Tfor 258 -#define Tin 259 -#define Twhile 260 -#define Tif 261 -#define Telse 262 -#define Tswitch 263 -#define Tcase 264 -#define Tcasebody 265 -#define Ttwiddle 266 -#define Tbang 267 -#define Tsubshell 268 -#define Tfunc 269 -#define Tredir 270 -#define Tdup 271 -#define Tpipe 272 -#define Tindex 273 -#define Tbasic 274 -#define Targs 275 -#define Tword 276 -#define Twords 277 -#define Tparen 278 -#define Tblock 279 -#define Tandand 280 -#define Toror 281 -#define Tcount 282 -#define Tjoin 283 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 24 "sys/cmd/rc/syntax.y" +#line 24 "src/cmd/rc/syntax.y" struct Tree *tree; -#line 127 "sys/cmd/rc/parse.h" +#line 96 "src/cmd/rc/parse.h" }; typedef union YYSTYPE YYSTYPE; @@ -134,8 +103,6 @@ typedef union YYSTYPE YYSTYPE; extern YYSTYPE yylval; - int yyparse (void); - -#endif /* !YY_YY_SYS_CMD_RC_PARSE_H_INCLUDED */ +#endif /* !YY_YY_SRC_CMD_RC_PARSE_H_INCLUDED */ diff --git a/src/cmd/rc/rc.h b/src/cmd/rc/rc.h index 9b415fc..f7533a0 100644 --- a/src/cmd/rc/rc.h +++ b/src/cmd/rc/rc.h @@ -139,7 +139,8 @@ struct Thread struct WaitItem *on; } wait; - int pid, pgid, status; + int pid, pgid; + int status; long line; Thread *caller; // process we return to @@ -261,3 +262,7 @@ char **mkenv(void); int compile(Tree *); Code *copycode(Code *c); void freecode(Code *c); + +/* glob.c */ +#define GLOB ((char)(0x01)) +int match(char *, char *, int); diff --git a/src/cmd/rc/rules.mk b/src/cmd/rc/rules.mk index 76837fc..206c517 100644 --- a/src/cmd/rc/rules.mk +++ b/src/cmd/rc/rules.mk @@ -15,6 +15,7 @@ SRCS_$(d):=\ $(d)/sys.c\ $(d)/wait.c\ $(d)/job.c\ + $(d)/glob.c\ $(d)/exec.c\ $(d)/main.c @@ -23,7 +24,7 @@ BINS_$(d) := $(d)/rc include share/paths.mk $(d)/parse.h $(d)/parse.c: $(d)/syntax.y - yacc --header=$(time[0] = u; msg->time[1] = s; msg->time[2] = u+s; - msg->status = WEXITSTATUS(status); msg->type = Pdone; + msg->status.code = WEXITSTATUS(status); + msg->status.str = nil; + return 1; } @@ -55,9 +61,11 @@ await(int pid4, int opt, struct WaitMsg *msg) msg->time[0] = u; msg->time[1] = s; msg->time[2] = u+s; - msg->status = WTERMSIG(status); msg->type = Psig; + msg->status.code = WTERMSIG(status); + msg->status.str = nil; + return 1; } @@ -66,7 +74,8 @@ await(int pid4, int opt, struct WaitMsg *msg) msg->time[0] = u; msg->time[1] = s; msg->time[2] = u+s; - msg->status = WSTOPSIG(status); + msg->status.code = WSTOPSIG(status); + msg->status.str = nil; msg->type = Pstop; return 1; @@ -88,22 +97,23 @@ shouldwait(Thread *job) return 0; } -static inline -void +static inline void notify(Thread *job, struct WaitMsg msg) { int i; for(i=0; i < job->wait.len; i++){ if(job->wait.on[i].pid == msg.pid){ - job->status = msg.status; + job->status = msg.status.code; switch(msg.type){ case Pstop: + /* NOTE: this needs to have an interactive check */ print(shell.err, "%d: suspended\n", msg.pid); job->wait.status = Pstop; job->wait.on[i].status = Pstop; break; case Psig: + /* NOTE: this needs to have an interactive check */ print(shell.err, "%d: terminated by signal %d\n", msg.pid, msg.status); /* fallthrough */ case Pdone: @@ -114,6 +124,7 @@ notify(Thread *job, struct WaitMsg msg) break; default: + /* NOTE: this needs to have an interactive check */ fatal("%d: unrecognized message type %d\n", msg.pid, msg.type); } break; -- cgit v1.2.1