aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/parse.c
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2021-10-20 13:10:54 -0700
committerNicholas Noll <nbnoll@eml.cc>2021-10-20 13:10:54 -0700
commit888679027c2e9b43d1485d970df8170ac4fda29f (patch)
treef46c257e6be1f47f4aa69d31a64643c76457a64b /sys/cmd/rc/parse.c
parent6d50d5b97d49a74a8faf587ec2bbf234626adf0c (diff)
Refactored interactivity to track with thread.
Hit a bit of a stopping point. Specifically, the way XAsync runs currently is by forking the execution context and having the child run the async code while the parent runs the remainder. The problem with this architecture is it doesn't interact well with job control. When we fork, we create a new process group. Thus the Xasync fork becomes the new leader. In short, our traversal of the parse tree as to be less "preorder" and more "in order", i.e. from the leaves up. The "left" command of the pipeline should be the "leader" of the process group.
Diffstat (limited to 'sys/cmd/rc/parse.c')
-rw-r--r--sys/cmd/rc/parse.c451
1 files changed, 261 insertions, 190 deletions
diff --git a/sys/cmd/rc/parse.c b/sys/cmd/rc/parse.c
index c53f514..edc1006 100644
--- a/sys/cmd/rc/parse.c
+++ b/sys/cmd/rc/parse.c
@@ -111,43 +111,51 @@ enum yysymbol_kind_t
YYSYMBOL_Telse = 6, /* Telse */
YYSYMBOL_Tbang = 7, /* Tbang */
YYSYMBOL_Tsubshell = 8, /* Tsubshell */
- YYSYMBOL_Targs = 9, /* Targs */
- YYSYMBOL_Tindex = 10, /* Tindex */
- YYSYMBOL_Tbasic = 11, /* Tbasic */
- YYSYMBOL_Tparen = 12, /* Tparen */
- YYSYMBOL_Tblock = 13, /* Tblock */
- YYSYMBOL_Twhile = 14, /* Twhile */
- YYSYMBOL_15_n_ = 15, /* '\n' */
- YYSYMBOL_16_ = 16, /* '$' */
- YYSYMBOL_Tcount = 17, /* Tcount */
- YYSYMBOL_Tflat = 18, /* Tflat */
- YYSYMBOL_19_ = 19, /* '(' */
- YYSYMBOL_20_ = 20, /* ')' */
- YYSYMBOL_21_ = 21, /* '{' */
- YYSYMBOL_22_ = 22, /* '}' */
- YYSYMBOL_23_ = 23, /* ';' */
- YYSYMBOL_24_ = 24, /* '&' */
- YYSYMBOL_25_ = 25, /* '=' */
- YYSYMBOL_26_ = 26, /* '^' */
- YYSYMBOL_YYACCEPT = 27, /* $accept */
- YYSYMBOL_rc = 28, /* rc */
- YYSYMBOL_line = 29, /* line */
- YYSYMBOL_body = 30, /* body */
- YYSYMBOL_paren = 31, /* paren */
- YYSYMBOL_block = 32, /* block */
- YYSYMBOL_cmds = 33, /* cmds */
- YYSYMBOL_cmdsln = 34, /* cmdsln */
- YYSYMBOL_ifbody = 35, /* ifbody */
- YYSYMBOL_assign = 36, /* assign */
- YYSYMBOL_cmd = 37, /* cmd */
- YYSYMBOL_basic = 38, /* basic */
- YYSYMBOL_atom = 39, /* atom */
- YYSYMBOL_word = 40, /* word */
- YYSYMBOL_executable = 41, /* executable */
- YYSYMBOL_nonkeyword = 42, /* nonkeyword */
- YYSYMBOL_keyword = 43, /* keyword */
- YYSYMBOL_wordsnl = 44, /* wordsnl */
- YYSYMBOL_nl = 45 /* nl */
+ YYSYMBOL_Toror = 9, /* Toror */
+ YYSYMBOL_Tandand = 10, /* Tandand */
+ YYSYMBOL_There = 11, /* There */
+ YYSYMBOL_Tredir = 12, /* Tredir */
+ YYSYMBOL_Tpipe = 13, /* Tpipe */
+ YYSYMBOL_Tdup = 14, /* Tdup */
+ YYSYMBOL_Tbasic = 15, /* Tbasic */
+ YYSYMBOL_Tparen = 16, /* Tparen */
+ YYSYMBOL_Tblock = 17, /* Tblock */
+ YYSYMBOL_Targs = 18, /* Targs */
+ YYSYMBOL_Tindex = 19, /* Tindex */
+ YYSYMBOL_Twhile = 20, /* Twhile */
+ YYSYMBOL_21_n_ = 21, /* '\n' */
+ YYSYMBOL_22_ = 22, /* '$' */
+ YYSYMBOL_Tcount = 23, /* Tcount */
+ YYSYMBOL_Tflat = 24, /* Tflat */
+ YYSYMBOL_25_ = 25, /* '(' */
+ YYSYMBOL_26_ = 26, /* ')' */
+ YYSYMBOL_27_ = 27, /* '{' */
+ YYSYMBOL_28_ = 28, /* '}' */
+ YYSYMBOL_29_ = 29, /* ';' */
+ YYSYMBOL_30_ = 30, /* '&' */
+ YYSYMBOL_31_ = 31, /* '=' */
+ YYSYMBOL_32_ = 32, /* '^' */
+ YYSYMBOL_YYACCEPT = 33, /* $accept */
+ YYSYMBOL_rc = 34, /* rc */
+ YYSYMBOL_line = 35, /* line */
+ YYSYMBOL_body = 36, /* body */
+ YYSYMBOL_paren = 37, /* paren */
+ YYSYMBOL_block = 38, /* block */
+ YYSYMBOL_cmds = 39, /* cmds */
+ YYSYMBOL_cmdsln = 40, /* cmdsln */
+ YYSYMBOL_ifbody = 41, /* ifbody */
+ YYSYMBOL_assign = 42, /* assign */
+ YYSYMBOL_redir = 43, /* redir */
+ YYSYMBOL_epilog = 44, /* epilog */
+ YYSYMBOL_cmd = 45, /* cmd */
+ YYSYMBOL_basic = 46, /* basic */
+ YYSYMBOL_atom = 47, /* atom */
+ YYSYMBOL_word = 48, /* word */
+ YYSYMBOL_executable = 49, /* executable */
+ YYSYMBOL_nonkeyword = 50, /* nonkeyword */
+ YYSYMBOL_keyword = 51, /* keyword */
+ YYSYMBOL_wordsnl = 52, /* wordsnl */
+ YYSYMBOL_nl = 53 /* nl */
};
typedef enum yysymbol_kind_t yysymbol_kind_t;
@@ -473,21 +481,21 @@ union yyalloc
#endif /* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 37
+#define YYFINAL 42
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 97
+#define YYLAST 158
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 27
+#define YYNTOKENS 33
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 19
+#define YYNNTS 21
/* YYNRULES -- Number of rules. */
-#define YYNRULES 45
+#define YYNRULES 52
/* YYNSTATES -- Number of states. */
-#define YYNSTATES 67
+#define YYNSTATES 79
/* YYMAXUTOK -- Last valid token kind. */
-#define YYMAXUTOK 271
+#define YYMAXUTOK 277
/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
@@ -502,18 +510,18 @@ union yyalloc
static const yytype_int8 yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 15, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 21, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 16, 2, 24, 2,
- 19, 20, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 23,
- 2, 25, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 22, 2, 30, 2,
+ 25, 26, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 29,
+ 2, 31, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 26, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 32, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 21, 2, 22, 2, 2, 2, 2,
+ 2, 2, 2, 27, 2, 28, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -528,18 +536,19 @@ static const yytype_int8 yytranslate[] =
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 17, 18
+ 15, 16, 17, 18, 19, 20, 23, 24
};
#if YYDEBUG
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_int8 yyrline[] =
{
- 0, 36, 36, 37, 40, 41, 44, 45, 48, 51,
- 54, 55, 58, 59, 62, 63, 66, 69, 70, 71,
- 72, 73, 74, 75, 78, 79, 88, 89, 92, 93,
- 96, 97, 100, 101, 102, 103, 104, 108, 108, 108,
- 108, 115, 116, 117, 119, 121
+ 0, 37, 37, 38, 41, 42, 45, 46, 49, 52,
+ 55, 56, 59, 60, 63, 64, 67, 70, 71, 74,
+ 75, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 89, 90, 91, 94, 95, 98, 99, 102, 103, 106,
+ 107, 108, 109, 110, 114, 114, 114, 114, 121, 122,
+ 123, 125, 127
};
#endif
@@ -556,12 +565,13 @@ static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
static const char *const yytname[] =
{
"\"end of file\"", "error", "\"invalid token\"", "Tword", "Twords",
- "Tif", "Telse", "Tbang", "Tsubshell", "Targs", "Tindex", "Tbasic",
- "Tparen", "Tblock", "Twhile", "'\\n'", "'$'", "Tcount", "Tflat", "'('",
- "')'", "'{'", "'}'", "';'", "'&'", "'='", "'^'", "$accept", "rc", "line",
- "body", "paren", "block", "cmds", "cmdsln", "ifbody", "assign", "cmd",
- "basic", "atom", "word", "executable", "nonkeyword", "keyword",
- "wordsnl", "nl", YY_NULLPTR
+ "Tif", "Telse", "Tbang", "Tsubshell", "Toror", "Tandand", "There",
+ "Tredir", "Tpipe", "Tdup", "Tbasic", "Tparen", "Tblock", "Targs",
+ "Tindex", "Twhile", "'\\n'", "'$'", "Tcount", "Tflat", "'('", "')'",
+ "'{'", "'}'", "';'", "'&'", "'='", "'^'", "$accept", "rc", "line",
+ "body", "paren", "block", "cmds", "cmdsln", "ifbody", "assign", "redir",
+ "epilog", "cmd", "basic", "atom", "word", "executable", "nonkeyword",
+ "keyword", "wordsnl", "nl", YY_NULLPTR
};
static const char *
@@ -571,7 +581,7 @@ yysymbol_name (yysymbol_kind_t yysymbol)
}
#endif
-#define YYPACT_NINF (-19)
+#define YYPACT_NINF (-42)
#define yypact_value_is_default(Yyn) \
((Yyn) == YYPACT_NINF)
@@ -583,15 +593,16 @@ yysymbol_name (yysymbol_kind_t yysymbol)
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-static const yytype_int8 yypact[] =
+static const yytype_int16 yypact[] =
{
- 18, -19, -18, 24, 24, 78, 78, 78, -19, 24,
- 5, 7, -19, 24, 24, -4, 78, 41, -19, 24,
- -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
- -19, -19, 72, -6, -19, 24, 29, -19, -19, -19,
- -19, -19, -19, -19, -2, 78, 78, 10, 55, -19,
- -19, -2, -19, -19, -19, 78, -2, -19, -19, -19,
- 43, -19, -19, -19, -19, 55, -19
+ 22, -42, -23, 89, 89, 133, -42, 133, 133, 133,
+ -42, 89, 18, 7, -5, 89, 89, 89, 24, 123,
+ 20, -42, 89, -42, 25, 25, -42, -42, -42, -42,
+ -42, 23, -42, -42, -42, -42, -42, 99, 15, -42,
+ 89, 35, -42, -42, -5, -42, -42, 25, 25, -42,
+ -42, -42, -42, 23, 133, 133, 36, 66, 133, -42,
+ -42, 23, -42, -42, -42, -42, 66, 23, -42, -42,
+ -42, 27, -42, 25, -42, -42, -42, 66, 25
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -599,27 +610,30 @@ static const yytype_int8 yypact[] =
means the default is an error. */
static const yytype_int8 yydefact[] =
{
- 17, 32, 0, 17, 17, 0, 0, 0, 41, 17,
- 0, 0, 19, 17, 17, 4, 18, 24, 30, 17,
- 44, 22, 23, 37, 38, 39, 40, 33, 26, 27,
- 35, 36, 0, 0, 12, 17, 6, 1, 3, 5,
- 20, 10, 11, 28, 25, 0, 0, 0, 17, 42,
- 34, 43, 9, 7, 13, 0, 16, 31, 8, 45,
- 19, 21, 14, 29, 44, 17, 15
+ 21, 39, 0, 21, 21, 0, 17, 0, 0, 0,
+ 48, 21, 0, 0, 19, 21, 21, 21, 4, 22,
+ 30, 37, 21, 51, 28, 29, 44, 45, 46, 47,
+ 35, 18, 33, 34, 40, 42, 43, 0, 0, 12,
+ 21, 6, 1, 3, 19, 23, 5, 26, 25, 51,
+ 10, 11, 32, 31, 0, 0, 0, 21, 0, 49,
+ 41, 50, 9, 7, 13, 20, 21, 16, 38, 8,
+ 52, 19, 27, 14, 36, 24, 51, 21, 15
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
- -19, -19, 42, -7, -19, 9, 2, -19, -19, -19,
- 0, -19, 4, 6, -19, 1, -19, -19, -10
+ -42, -42, 46, 10, -42, 19, 11, -42, -42, -42,
+ -13, 28, 0, -42, 12, -14, -42, 5, -42, -42,
+ -41
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
- 0, 10, 11, 33, 20, 12, 34, 35, 61, 14,
- 36, 16, 43, 44, 17, 18, 29, 32, 48
+ 0, 12, 13, 38, 23, 14, 39, 40, 72, 16,
+ 17, 45, 41, 19, 30, 31, 20, 21, 33, 37,
+ 57
};
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
@@ -627,63 +641,78 @@ static const yytype_int8 yydefgoto[] =
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_int8 yytable[] =
{
- 15, 19, 13, 21, 22, 37, 28, 28, 28, 27,
- 30, 31, 47, 15, 40, 13, 52, 28, -2, 41,
- 42, 1, 38, 2, 55, 3, 4, 1, 53, 2,
- 58, 3, 4, 28, 5, 6, 7, 8, 51, 9,
- 5, 6, 7, 8, 54, 9, 28, 28, 62, 64,
- 57, 56, 41, 42, 65, 39, 28, 60, 1, 63,
- 2, 0, 3, 4, 0, 66, 45, 46, 0, 0,
- 59, 5, 6, 7, 8, 1, 9, 23, 24, 25,
- 26, 1, 0, 23, 24, 25, 26, 49, 5, 6,
- 7, 8, 50, 0, 5, 6, 7, 8
+ 18, 44, 22, 24, 25, 53, 52, 5, 66, 6,
+ 32, 15, 32, 32, 32, 18, 47, 48, 42, 34,
+ 35, 36, -2, 61, 32, 1, 15, 2, 43, 3,
+ 4, 44, 56, 76, 5, 77, 6, 49, 49, 5,
+ 67, 6, 32, 62, 7, 8, 9, 10, 49, 11,
+ 63, 54, 55, 50, 51, 58, 64, 73, 44, 32,
+ 32, 46, 69, 32, 50, 51, 75, 68, 0, 1,
+ 74, 2, 65, 3, 4, 0, 71, 78, 5, 0,
+ 6, 0, 0, 0, 0, 0, 0, 70, 7, 8,
+ 9, 10, 1, 11, 2, 0, 3, 4, 0, 0,
+ 0, 5, 1, 6, 26, 27, 28, 29, 0, 0,
+ 0, 7, 8, 9, 10, 0, 11, 0, 0, 0,
+ 59, 7, 8, 9, 10, 60, 1, 0, 26, 27,
+ 28, 29, 0, 0, 0, 5, 1, 6, 26, 27,
+ 28, 29, 0, 0, 0, 7, 8, 9, 10, 0,
+ 0, 0, 0, 0, 0, 7, 8, 9, 10
};
static const yytype_int8 yycheck[] =
{
- 0, 19, 0, 3, 4, 0, 5, 6, 7, 5,
- 6, 7, 19, 13, 14, 13, 22, 16, 0, 23,
- 24, 3, 15, 5, 26, 7, 8, 3, 35, 5,
- 20, 7, 8, 32, 16, 17, 18, 19, 32, 21,
- 16, 17, 18, 19, 15, 21, 45, 46, 48, 6,
- 46, 45, 23, 24, 64, 13, 55, 48, 3, 55,
- 5, -1, 7, 8, -1, 65, 25, 26, -1, -1,
- 15, 16, 17, 18, 19, 3, 21, 5, 6, 7,
- 8, 3, -1, 5, 6, 7, 8, 15, 16, 17,
- 18, 19, 20, -1, 16, 17, 18, 19
+ 0, 14, 25, 3, 4, 19, 19, 12, 49, 14,
+ 5, 0, 7, 8, 9, 15, 16, 17, 0, 7,
+ 8, 9, 0, 37, 19, 3, 15, 5, 21, 7,
+ 8, 44, 22, 6, 12, 76, 14, 13, 13, 12,
+ 54, 14, 37, 28, 22, 23, 24, 25, 13, 27,
+ 40, 31, 32, 29, 30, 32, 21, 57, 71, 54,
+ 55, 15, 26, 58, 29, 30, 66, 55, -1, 3,
+ 58, 5, 44, 7, 8, -1, 57, 77, 12, -1,
+ 14, -1, -1, -1, -1, -1, -1, 21, 22, 23,
+ 24, 25, 3, 27, 5, -1, 7, 8, -1, -1,
+ -1, 12, 3, 14, 5, 6, 7, 8, -1, -1,
+ -1, 22, 23, 24, 25, -1, 27, -1, -1, -1,
+ 21, 22, 23, 24, 25, 26, 3, -1, 5, 6,
+ 7, 8, -1, -1, -1, 12, 3, 14, 5, 6,
+ 7, 8, -1, -1, -1, 22, 23, 24, 25, -1,
+ -1, -1, -1, -1, -1, 22, 23, 24, 25
};
/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
state STATE-NUM. */
static const yytype_int8 yystos[] =
{
- 0, 3, 5, 7, 8, 16, 17, 18, 19, 21,
- 28, 29, 32, 33, 36, 37, 38, 41, 42, 19,
- 31, 37, 37, 5, 6, 7, 8, 39, 42, 43,
- 39, 39, 44, 30, 33, 34, 37, 0, 15, 29,
- 37, 23, 24, 39, 40, 25, 26, 30, 45, 15,
- 20, 40, 22, 30, 15, 26, 40, 39, 20, 15,
- 32, 35, 37, 39, 6, 45, 37
+ 0, 3, 5, 7, 8, 12, 14, 22, 23, 24,
+ 25, 27, 34, 35, 38, 39, 42, 43, 45, 46,
+ 49, 50, 25, 37, 45, 45, 5, 6, 7, 8,
+ 47, 48, 50, 51, 47, 47, 47, 52, 36, 39,
+ 40, 45, 0, 21, 43, 44, 35, 45, 45, 13,
+ 29, 30, 43, 48, 31, 32, 36, 53, 32, 21,
+ 26, 48, 28, 36, 21, 44, 53, 48, 47, 26,
+ 21, 38, 41, 45, 47, 45, 6, 53, 45
};
/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
static const yytype_int8 yyr1[] =
{
- 0, 27, 28, 28, 29, 29, 30, 30, 31, 32,
- 33, 33, 34, 34, 35, 35, 36, 37, 37, 37,
- 37, 37, 37, 37, 38, 38, 39, 39, 40, 40,
- 41, 41, 42, 42, 42, 42, 42, 43, 43, 43,
- 43, 44, 44, 44, 45, 45
+ 0, 33, 34, 34, 35, 35, 36, 36, 37, 38,
+ 39, 39, 40, 40, 41, 41, 42, 43, 43, 44,
+ 44, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 46, 46, 46, 47, 47, 48, 48, 49, 49, 50,
+ 50, 50, 50, 50, 51, 51, 51, 51, 52, 52,
+ 52, 53, 53
};
/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
static const yytype_int8 yyr2[] =
{
0, 2, 0, 2, 1, 2, 1, 2, 3, 3,
- 2, 2, 1, 2, 1, 4, 3, 0, 1, 1,
- 2, 4, 2, 2, 1, 2, 1, 1, 1, 3,
- 1, 3, 1, 2, 3, 2, 2, 1, 1, 1,
- 1, 0, 2, 2, 0, 2
+ 2, 2, 1, 2, 1, 4, 3, 1, 2, 0,
+ 2, 0, 1, 2, 4, 2, 2, 4, 2, 2,
+ 1, 2, 2, 1, 1, 1, 3, 1, 3, 1,
+ 2, 3, 2, 2, 1, 1, 1, 1, 0, 2,
+ 2, 0, 2
};
@@ -1417,163 +1446,205 @@ yyreduce:
switch (yyn)
{
case 2: /* rc: %empty */
-#line 36 "sys/cmd/rc/syntax.y"
+#line 37 "sys/cmd/rc/syntax.y"
{ return 0; }
-#line 1423 "sys/cmd/rc/parse.c"
+#line 1452 "sys/cmd/rc/parse.c"
break;
case 3: /* rc: line '\n' */
-#line 37 "sys/cmd/rc/syntax.y"
+#line 38 "sys/cmd/rc/syntax.y"
{ return compile((yyvsp[-1].tree)); }
-#line 1429 "sys/cmd/rc/parse.c"
+#line 1458 "sys/cmd/rc/parse.c"
break;
case 5: /* line: cmds line */
-#line 41 "sys/cmd/rc/syntax.y"
+#line 42 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(';', (yyvsp[-1].tree), (yyvsp[0].tree)); }
-#line 1435 "sys/cmd/rc/parse.c"
+#line 1464 "sys/cmd/rc/parse.c"
break;
case 7: /* body: cmdsln body */
-#line 45 "sys/cmd/rc/syntax.y"
+#line 46 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(';', (yyvsp[-1].tree), (yyvsp[0].tree)); }
-#line 1441 "sys/cmd/rc/parse.c"
+#line 1470 "sys/cmd/rc/parse.c"
break;
case 8: /* paren: '(' body ')' */
-#line 48 "sys/cmd/rc/syntax.y"
+#line 49 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tparen, (yyvsp[-1].tree)); }
-#line 1447 "sys/cmd/rc/parse.c"
+#line 1476 "sys/cmd/rc/parse.c"
break;
case 9: /* block: '{' body '}' */
-#line 51 "sys/cmd/rc/syntax.y"
+#line 52 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tblock, (yyvsp[-1].tree)); }
-#line 1453 "sys/cmd/rc/parse.c"
+#line 1482 "sys/cmd/rc/parse.c"
break;
case 11: /* cmds: cmd '&' */
-#line 55 "sys/cmd/rc/syntax.y"
+#line 56 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1('&', (yyvsp[-1].tree)); }
-#line 1459 "sys/cmd/rc/parse.c"
+#line 1488 "sys/cmd/rc/parse.c"
break;
case 14: /* ifbody: cmd */
-#line 62 "sys/cmd/rc/syntax.y"
+#line 63 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(Tif, nil, (yyvsp[0].tree)); }
-#line 1465 "sys/cmd/rc/parse.c"
+#line 1494 "sys/cmd/rc/parse.c"
break;
case 15: /* ifbody: block Telse nl cmd */
-#line 63 "sys/cmd/rc/syntax.y"
+#line 64 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree3(Tif, nil, (yyvsp[-3].tree), (yyvsp[-2].tree)); }
-#line 1471 "sys/cmd/rc/parse.c"
+#line 1500 "sys/cmd/rc/parse.c"
break;
case 16: /* assign: executable '=' word */
-#line 66 "sys/cmd/rc/syntax.y"
+#line 67 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2('=', (yyvsp[-2].tree), (yyvsp[0].tree)); }
-#line 1477 "sys/cmd/rc/parse.c"
+#line 1506 "sys/cmd/rc/parse.c"
break;
- case 17: /* cmd: %empty */
-#line 69 "sys/cmd/rc/syntax.y"
+ case 18: /* redir: Tredir word */
+#line 71 "sys/cmd/rc/syntax.y"
+ { (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 0); }
+#line 1512 "sys/cmd/rc/parse.c"
+ break;
+
+ case 19: /* epilog: %empty */
+#line 74 "sys/cmd/rc/syntax.y"
+ { (yyval.tree) = nil; }
+#line 1518 "sys/cmd/rc/parse.c"
+ break;
+
+ case 20: /* epilog: redir epilog */
+#line 75 "sys/cmd/rc/syntax.y"
+ { (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 1); }
+#line 1524 "sys/cmd/rc/parse.c"
+ break;
+
+ case 21: /* cmd: %empty */
+#line 78 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = nil; }
-#line 1483 "sys/cmd/rc/parse.c"
+#line 1530 "sys/cmd/rc/parse.c"
break;
- case 18: /* cmd: basic */
-#line 70 "sys/cmd/rc/syntax.y"
+ case 22: /* cmd: basic */
+#line 79 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tbasic, (yyvsp[0].tree)); }
-#line 1489 "sys/cmd/rc/parse.c"
+#line 1536 "sys/cmd/rc/parse.c"
break;
- case 20: /* cmd: assign cmd */
-#line 72 "sys/cmd/rc/syntax.y"
+ case 23: /* cmd: block epilog */
+#line 80 "sys/cmd/rc/syntax.y"
+ { (yyval.tree) = hangepilog((yyvsp[-1].tree), (yyvsp[0].tree)); }
+#line 1542 "sys/cmd/rc/parse.c"
+ break;
+
+ case 24: /* cmd: cmd Tpipe nl cmd */
+#line 81 "sys/cmd/rc/syntax.y"
+ { (yyval.tree) = hangchild2((yyvsp[-2].tree), (yyvsp[-3].tree), 0, (yyvsp[0].tree), 1); }
+#line 1548 "sys/cmd/rc/parse.c"
+ break;
+
+ case 25: /* cmd: redir cmd */
+#line 82 "sys/cmd/rc/syntax.y"
+ { (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 1); }
+#line 1554 "sys/cmd/rc/parse.c"
+ break;
+
+ case 26: /* cmd: assign cmd */
+#line 83 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 2); }
-#line 1495 "sys/cmd/rc/parse.c"
+#line 1560 "sys/cmd/rc/parse.c"
break;
- case 21: /* cmd: Tif paren nl ifbody */
-#line 73 "sys/cmd/rc/syntax.y"
+ case 27: /* cmd: Tif paren nl ifbody */
+#line 84 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = hangchild1((yyvsp[-2].tree), (yyvsp[-3].tree), 0); }
-#line 1501 "sys/cmd/rc/parse.c"
+#line 1566 "sys/cmd/rc/parse.c"
break;
- case 22: /* cmd: Tbang cmd */
-#line 74 "sys/cmd/rc/syntax.y"
+ case 28: /* cmd: Tbang cmd */
+#line 85 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tbang, (yyvsp[0].tree)); }
-#line 1507 "sys/cmd/rc/parse.c"
+#line 1572 "sys/cmd/rc/parse.c"
break;
- case 23: /* cmd: Tsubshell cmd */
-#line 75 "sys/cmd/rc/syntax.y"
+ case 29: /* cmd: Tsubshell cmd */
+#line 86 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tsubshell, (yyvsp[0].tree)); }
-#line 1513 "sys/cmd/rc/parse.c"
+#line 1578 "sys/cmd/rc/parse.c"
break;
- case 25: /* basic: basic word */
-#line 79 "sys/cmd/rc/syntax.y"
- { (yyval.tree) = maketree2(Targs, (yyvsp[-1].tree), (yyvsp[0].tree)); }
-#line 1519 "sys/cmd/rc/parse.c"
+ case 31: /* basic: basic word */
+#line 90 "sys/cmd/rc/syntax.y"
+ { (yyval.tree) = maketree2(Targs, (yyvsp[-1].tree), (yyvsp[0].tree)); }
+#line 1584 "sys/cmd/rc/parse.c"
+ break;
+
+ case 32: /* basic: basic redir */
+#line 91 "sys/cmd/rc/syntax.y"
+ { (yyval.tree) = maketree2(Targs, (yyvsp[-1].tree), (yyvsp[0].tree)); }
+#line 1590 "sys/cmd/rc/parse.c"
break;
- case 27: /* atom: keyword */
-#line 89 "sys/cmd/rc/syntax.y"
+ case 34: /* atom: keyword */
+#line 95 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tword, (yyvsp[0].tree)); }
-#line 1525 "sys/cmd/rc/parse.c"
+#line 1596 "sys/cmd/rc/parse.c"
break;
- case 29: /* word: word '^' atom */
-#line 93 "sys/cmd/rc/syntax.y"
+ case 36: /* word: word '^' atom */
+#line 99 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2('^', (yyvsp[-2].tree), (yyvsp[0].tree)); }
-#line 1531 "sys/cmd/rc/parse.c"
+#line 1602 "sys/cmd/rc/parse.c"
break;
- case 31: /* executable: executable '^' atom */
-#line 97 "sys/cmd/rc/syntax.y"
+ case 38: /* executable: executable '^' atom */
+#line 103 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2('^', (yyvsp[-2].tree), (yyvsp[0].tree)); }
-#line 1537 "sys/cmd/rc/parse.c"
+#line 1608 "sys/cmd/rc/parse.c"
break;
- case 33: /* nonkeyword: '$' atom */
-#line 101 "sys/cmd/rc/syntax.y"
+ case 40: /* nonkeyword: '$' atom */
+#line 107 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1('$', (yyvsp[0].tree)); }
-#line 1543 "sys/cmd/rc/parse.c"
+#line 1614 "sys/cmd/rc/parse.c"
break;
- case 34: /* nonkeyword: '(' wordsnl ')' */
-#line 102 "sys/cmd/rc/syntax.y"
+ case 41: /* nonkeyword: '(' wordsnl ')' */
+#line 108 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = (yyvsp[-1].tree); }
-#line 1549 "sys/cmd/rc/parse.c"
+#line 1620 "sys/cmd/rc/parse.c"
break;
- case 35: /* nonkeyword: Tcount atom */
-#line 103 "sys/cmd/rc/syntax.y"
+ case 42: /* nonkeyword: Tcount atom */
+#line 109 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tcount, (yyvsp[0].tree)); }
-#line 1555 "sys/cmd/rc/parse.c"
+#line 1626 "sys/cmd/rc/parse.c"
break;
- case 36: /* nonkeyword: Tflat atom */
-#line 104 "sys/cmd/rc/syntax.y"
+ case 43: /* nonkeyword: Tflat atom */
+#line 110 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tflat, (yyvsp[0].tree)); }
-#line 1561 "sys/cmd/rc/parse.c"
+#line 1632 "sys/cmd/rc/parse.c"
break;
- case 41: /* wordsnl: %empty */
-#line 115 "sys/cmd/rc/syntax.y"
+ case 48: /* wordsnl: %empty */
+#line 121 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = nil; }
-#line 1567 "sys/cmd/rc/parse.c"
+#line 1638 "sys/cmd/rc/parse.c"
break;
- case 43: /* wordsnl: wordsnl word */
-#line 117 "sys/cmd/rc/syntax.y"
+ case 50: /* wordsnl: wordsnl word */
+#line 123 "sys/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 1573 "sys/cmd/rc/parse.c"
+#line 1644 "sys/cmd/rc/parse.c"
break;
-#line 1577 "sys/cmd/rc/parse.c"
+#line 1648 "sys/cmd/rc/parse.c"
default: break;
}
@@ -1797,5 +1868,5 @@ yyreturnlab:
return yyresult;
}
-#line 122 "sys/cmd/rc/syntax.y"
+#line 128 "sys/cmd/rc/syntax.y"