aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas <nbnoll@eml.cc>2021-11-15 15:08:03 -0800
committerNicholas <nbnoll@eml.cc>2021-11-15 15:08:14 -0800
commite9ff1c6fbbbac9ece2604876ab589ac282360446 (patch)
tree1e1378a1cb37ca4e751d8140eeed99db7ccc4ce7
parent27d656be97f1544d7535d8c144ff28b9214aed97 (diff)
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.
-rw-r--r--src/cmd/rc/code.c83
-rw-r--r--src/cmd/rc/exec.c63
-rw-r--r--src/cmd/rc/exec.h2
-rw-r--r--src/cmd/rc/glob.c82
-rw-r--r--src/cmd/rc/lex.c16
-rw-r--r--src/cmd/rc/main.c3
-rw-r--r--src/cmd/rc/parse.c675
-rw-r--r--src/cmd/rc/parse.h47
-rw-r--r--src/cmd/rc/rc.h7
-rw-r--r--src/cmd/rc/rules.mk3
-rw-r--r--src/cmd/rc/syntax.y38
-rw-r--r--src/cmd/rc/wait.c25
12 files changed, 616 insertions, 428 deletions
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 */
@@ -633,12 +658,20 @@ Xword(void)
}
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;
@@ -663,6 +696,27 @@ Xgoto(void)
}
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)
{
if(!runner->args->word){
@@ -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=$(<D)/parse.h --output=$(<D)/parse.c $(<)
+ bison --debug --defines=$(<D)/parse.h --output=$(<D)/parse.c $(<)
# local rules
$(BINS_$(d)): $(OBJS_$(d)) $(OBJ_DIR)/libutf/libutf.a $(OBJ_DIR)/base/base.a $(d)/parse.h
diff --git a/src/cmd/rc/syntax.y b/src/cmd/rc/syntax.y
index 0bdc776..9750002 100644
--- a/src/cmd/rc/syntax.y
+++ b/src/cmd/rc/syntax.y
@@ -65,13 +65,11 @@ ifbody:
| block Telse nl cmd { $$ = maketree3(Tif, nil, $1, $2); }
case:
- Tcase words ';' { $$ = hangchild1($1, $2, 0); }
-| Tcase words '\n' { $$ = hangchild1($1, $2, 0); }
+ Tcase words ';' nl cmdsln { $$ = hangchild2($1, $2, 0, $5, 1);}
casebody:
- cmd { $$ = maketree2(Tcasebody, $1, nil); }
-| case casebody { $$ = maketree2(Tcasebody, $1, $2); }
-| cmdsln casebody { $$ = maketree2(Tcasebody, $1, $2); }
+ /* empty */ { $$ = nil; }
+| case casebody { $$ = (!$2) ? $1 : maketree2(';', $1, $2); }
assign:
executable '=' word { $$ = maketree2('=', $1, $3); }
@@ -85,21 +83,21 @@ epilog:
| redir epilog { $$ = hangchild1($1, $2, 1); }
cmd:
-/* empty */ %prec Twhile { $$ = nil; }
-| basic { $$ = maketree1(Tbasic, $1); }
-| block epilog { $$ = hangepilog($1, $2); }
-| cmd Tpipe nl cmd { $$ = hangchild2($2, $1, 0, $4, 1); }
-| cmd Tandand nl cmd { $$ = maketree2(Tandand, $1, $4); }
-| cmd Toror nl cmd { $$ = maketree2(Toror, $1, $4); }
-| redir cmd %prec Tbang { $$ = hangchild1($1, $2, 1); }
-| assign cmd %prec Tbang { $$ = hangchild1($1, $2, 2); }
-| Tbang cmd { $$ = maketree1(Tbang, $2); }
-| Tsubshell cmd { $$ = maketree1(Tsubshell, $2); }
-| Tfor '(' word ')' nl cmd { $$ = hangchild3($1, $3, nil, $6); }
-| Tfor '(' word Tin words ')' nl cmd { $$ = hangchild3($1, $3, $5, $8); }
-| Twhile paren nl cmd { $$ = hangchild2($1, $2, 0, $4, 1); }
-| Tif paren nl ifbody { $$ = hangchild1($2, $1, 0); }
-| Tswitch '(' word ')' nl '{' casebody '}' { $$ = hangchild2($1, $3, 0, $7, 1); }
+/* empty */ %prec Twhile { $$ = nil; }
+| basic { $$ = maketree1(Tbasic, $1); }
+| block epilog { $$ = hangepilog($1, $2); }
+| cmd Tpipe nl cmd { $$ = hangchild2($2, $1, 0, $4, 1); }
+| cmd Tandand nl cmd { $$ = maketree2(Tandand, $1, $4); }
+| cmd Toror nl cmd { $$ = maketree2(Toror, $1, $4); }
+| redir cmd %prec Tbang { $$ = hangchild1($1, $2, 1); }
+| assign cmd %prec Tbang { $$ = hangchild1($1, $2, 2); }
+| Tbang cmd { $$ = maketree1(Tbang, $2); }
+| Tsubshell cmd { $$ = maketree1(Tsubshell, $2); }
+| Tfor '(' word ')' nl cmd { $$ = hangchild3($1, $3, nil, $6); }
+| Tfor '(' word Tin words ')' nl cmd { $$ = hangchild3($1, $3, $5, $8); }
+| Twhile paren nl cmd { $$ = hangchild2($1, $2, 0, $4, 1); }
+| Tif paren nl ifbody { $$ = hangchild1($2, $2, 0); }
+| Tswitch '(' word ')' nl '{' nl casebody '}' { $$ = hangchild2($1, $3, 0, $8, 1); }
basic:
executable
diff --git a/src/cmd/rc/wait.c b/src/cmd/rc/wait.c
index 911601c..295cc57 100644
--- a/src/cmd/rc/wait.c
+++ b/src/cmd/rc/wait.c
@@ -10,7 +10,11 @@ struct WaitMsg
int pid;
int type;
ulong time[3];
- int status;
+ struct{
+ int code;
+ char *str;
+ }status;
+ char *str;
};
// -----------------------------------------------------------------------
@@ -44,9 +48,11 @@ await(int pid4, int opt, struct WaitMsg *msg)
msg->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;