restore yyrecursive context in quitenv (LP#1069428)
This commit is contained in:
		
							
								
								
									
										6
									
								
								check.t
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								check.t
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| # $MirOS: src/bin/mksh/check.t,v 1.562 2012/10/22 20:19:10 tg Exp $ | # $MirOS: src/bin/mksh/check.t,v 1.563 2012/10/30 20:07:10 tg Exp $ | ||||||
| # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ | # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ | ||||||
| # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ | # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ | ||||||
| # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ | # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ | ||||||
| @@ -29,7 +29,7 @@ | |||||||
| # http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD | # http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD | ||||||
|  |  | ||||||
| expected-stdout: | expected-stdout: | ||||||
| 	@(#)MIRBSD KSH R40 2012/10/22 | 	@(#)MIRBSD KSH R40 2012/10/30 | ||||||
| description: | description: | ||||||
| 	Check version of shell. | 	Check version of shell. | ||||||
| stdin: | stdin: | ||||||
| @@ -38,7 +38,7 @@ name: KSH_VERSION | |||||||
| category: shell:legacy-no | category: shell:legacy-no | ||||||
| --- | --- | ||||||
| expected-stdout: | expected-stdout: | ||||||
| 	@(#)LEGACY KSH R40 2012/10/22 | 	@(#)LEGACY KSH R40 2012/10/30 | ||||||
| description: | description: | ||||||
| 	Check version of legacy shell. | 	Check version of legacy shell. | ||||||
| stdin: | stdin: | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								main.c
									
									
									
									
									
								
							| @@ -34,7 +34,7 @@ | |||||||
| #include <locale.h> | #include <locale.h> | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| __RCSID("$MirOS: src/bin/mksh/main.c,v 1.234 2012/10/30 20:07:00 tg Exp $"); | __RCSID("$MirOS: src/bin/mksh/main.c,v 1.235 2012/10/30 20:07:12 tg Exp $"); | ||||||
|  |  | ||||||
| extern char **environ; | extern char **environ; | ||||||
|  |  | ||||||
| @@ -925,6 +925,7 @@ newenv(int type) | |||||||
| 	ep->loc = e->loc; | 	ep->loc = e->loc; | ||||||
| 	ep->savefd = NULL; | 	ep->savefd = NULL; | ||||||
| 	ep->temps = NULL; | 	ep->temps = NULL; | ||||||
|  | 	ep->yyrecursive_statep = NULL; | ||||||
| 	ep->type = type; | 	ep->type = type; | ||||||
| 	ep->flags = 0; | 	ep->flags = 0; | ||||||
| 	/* jump buffer is invalid because flags == 0 */ | 	/* jump buffer is invalid because flags == 0 */ | ||||||
| @@ -938,6 +939,8 @@ quitenv(struct shf *shf) | |||||||
| 	char *cp; | 	char *cp; | ||||||
| 	int fd; | 	int fd; | ||||||
|  |  | ||||||
|  | 	while (e->yyrecursive_statep) | ||||||
|  | 		yyrecursive_pop(); | ||||||
| 	if (ep->oenv && ep->oenv->loc != ep->loc) | 	if (ep->oenv && ep->oenv->loc != ep->loc) | ||||||
| 		popblock(); | 		popblock(); | ||||||
| 	if (ep->savefd != NULL) { | 	if (ep->savefd != NULL) { | ||||||
|   | |||||||
							
								
								
									
										9
									
								
								sh.h
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								sh.h
									
									
									
									
									
								
							| @@ -157,9 +157,9 @@ | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifdef EXTERN | #ifdef EXTERN | ||||||
| __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.597 2012/10/22 20:19:16 tg Exp $"); | __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.598 2012/10/30 20:07:13 tg Exp $"); | ||||||
| #endif | #endif | ||||||
| #define MKSH_VERSION "R40 2012/10/22" | #define MKSH_VERSION "R40 2012/10/30" | ||||||
|  |  | ||||||
| /* arithmetic types: C implementation */ | /* arithmetic types: C implementation */ | ||||||
| #if !HAVE_CAN_INTTYPES | #if !HAVE_CAN_INTTYPES | ||||||
| @@ -646,6 +646,8 @@ enum sh_flag { | |||||||
| #define kshlongjmp	siglongjmp | #define kshlongjmp	siglongjmp | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | struct yyrecursive_state; | ||||||
|  |  | ||||||
| extern struct env { | extern struct env { | ||||||
| 	ALLOC_ITEM alloc_INT;	/* internal, do not touch */ | 	ALLOC_ITEM alloc_INT;	/* internal, do not touch */ | ||||||
| 	Area area;		/* temporary allocation area */ | 	Area area;		/* temporary allocation area */ | ||||||
| @@ -653,6 +655,8 @@ extern struct env { | |||||||
| 	struct block *loc;	/* local variables and functions */ | 	struct block *loc;	/* local variables and functions */ | ||||||
| 	short *savefd;		/* original redirected fds */ | 	short *savefd;		/* original redirected fds */ | ||||||
| 	struct temp *temps;	/* temp files */ | 	struct temp *temps;	/* temp files */ | ||||||
|  | 	/* saved parser recursion state */ | ||||||
|  | 	struct yyrecursive_state *yyrecursive_statep; | ||||||
| 	kshjmp_buf jbuf;	/* long jump back to env creator */ | 	kshjmp_buf jbuf;	/* long jump back to env creator */ | ||||||
| 	uint8_t type;		/* environment type - see below */ | 	uint8_t type;		/* environment type - see below */ | ||||||
| 	uint8_t flags;		/* EF_* */ | 	uint8_t flags;		/* EF_* */ | ||||||
| @@ -1929,6 +1933,7 @@ void initkeywords(void); | |||||||
| struct op *compile(Source *, bool); | struct op *compile(Source *, bool); | ||||||
| bool parse_usec(const char *, struct timeval *); | bool parse_usec(const char *, struct timeval *); | ||||||
| char *yyrecursive(int); | char *yyrecursive(int); | ||||||
|  | void yyrecursive_pop(void); | ||||||
| /* tree.c */ | /* tree.c */ | ||||||
| void fptreef(struct shf *, int, const char *, ...); | void fptreef(struct shf *, int, const char *, ...); | ||||||
| char *snptreef(char *, ssize_t, const char *, ...); | char *snptreef(char *, ssize_t, const char *, ...); | ||||||
|   | |||||||
							
								
								
									
										52
									
								
								syn.c
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								syn.c
									
									
									
									
									
								
							| @@ -23,7 +23,7 @@ | |||||||
|  |  | ||||||
| #include "sh.h" | #include "sh.h" | ||||||
|  |  | ||||||
| __RCSID("$MirOS: src/bin/mksh/syn.c,v 1.82 2012/10/22 20:19:18 tg Exp $"); | __RCSID("$MirOS: src/bin/mksh/syn.c,v 1.83 2012/10/30 20:07:15 tg Exp $"); | ||||||
|  |  | ||||||
| extern int subshell_nesting_type; | extern int subshell_nesting_type; | ||||||
| extern void yyskiputf8bom(void); | extern void yyskiputf8bom(void); | ||||||
| @@ -33,6 +33,15 @@ struct nesting_state { | |||||||
| 	int start_line;		/* line nesting began on */ | 	int start_line;		/* line nesting began on */ | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | struct yyrecursive_state { | ||||||
|  | 	struct yyrecursive_state *next; | ||||||
|  | 	struct ioword **old_herep; | ||||||
|  | 	int old_symbol; | ||||||
|  | 	int old_salias; | ||||||
|  | 	int old_nesting_type; | ||||||
|  | 	bool old_reject; | ||||||
|  | }; | ||||||
|  |  | ||||||
| static void yyparse(void); | static void yyparse(void); | ||||||
| static struct op *pipeline(int); | static struct op *pipeline(int); | ||||||
| static struct op *andor(void); | static struct op *andor(void); | ||||||
| @@ -1122,9 +1131,7 @@ yyrecursive(int subtype MKSH_A_UNUSED) | |||||||
| { | { | ||||||
| 	struct op *t; | 	struct op *t; | ||||||
| 	char *cp; | 	char *cp; | ||||||
| 	bool old_reject; | 	struct yyrecursive_state *ys; | ||||||
| 	int old_symbol, old_salias, old_nesting_type; |  | ||||||
| 	struct ioword **old_herep; |  | ||||||
| 	int stok, etok; | 	int stok, etok; | ||||||
|  |  | ||||||
| #ifndef MKSH_DISABLE_EXPERIMENTAL | #ifndef MKSH_DISABLE_EXPERIMENTAL | ||||||
| @@ -1138,28 +1145,45 @@ yyrecursive(int subtype MKSH_A_UNUSED) | |||||||
| 		etok = ')'; | 		etok = ')'; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	ys = alloc(sizeof(struct yyrecursive_state), ATEMP); | ||||||
|  |  | ||||||
| 	/* tell the lexer to accept a closing parenthesis as EOD */ | 	/* tell the lexer to accept a closing parenthesis as EOD */ | ||||||
| 	old_nesting_type = subshell_nesting_type; | 	ys->old_nesting_type = subshell_nesting_type; | ||||||
| 	subshell_nesting_type = etok; | 	subshell_nesting_type = etok; | ||||||
|  |  | ||||||
| 	/* push reject state, parse recursively, pop reject state */ | 	/* push reject state, parse recursively, pop reject state */ | ||||||
| 	old_reject = reject; | 	ys->old_reject = reject; | ||||||
| 	old_symbol = symbol; | 	ys->old_symbol = symbol; | ||||||
| 	ACCEPT; | 	ACCEPT; | ||||||
| 	old_herep = herep; | 	ys->old_herep = herep; | ||||||
| 	old_salias = sALIAS; | 	ys->old_salias = sALIAS; | ||||||
| 	sALIAS = 0; | 	sALIAS = 0; | ||||||
|  | 	ys->next = e->yyrecursive_statep; | ||||||
|  | 	e->yyrecursive_statep = ys; | ||||||
| 	/* we use TPAREN as a helper container here */ | 	/* we use TPAREN as a helper container here */ | ||||||
| 	t = nested(TPAREN, stok, etok); | 	t = nested(TPAREN, stok, etok); | ||||||
| 	sALIAS = old_salias; | 	yyrecursive_pop(); | ||||||
| 	herep = old_herep; |  | ||||||
| 	reject = old_reject; |  | ||||||
| 	symbol = old_symbol; |  | ||||||
|  |  | ||||||
| 	/* t->left because nested(TPAREN, ...) hides our goodies there */ | 	/* t->left because nested(TPAREN, ...) hides our goodies there */ | ||||||
| 	cp = snptreef(NULL, 0, "%T", t->left); | 	cp = snptreef(NULL, 0, "%T", t->left); | ||||||
| 	tfree(t, ATEMP); | 	tfree(t, ATEMP); | ||||||
|  |  | ||||||
| 	subshell_nesting_type = old_nesting_type; |  | ||||||
| 	return (cp); | 	return (cp); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | yyrecursive_pop(void) | ||||||
|  | { | ||||||
|  | 	struct yyrecursive_state *ys = e->yyrecursive_statep; | ||||||
|  |  | ||||||
|  | 	e->yyrecursive_statep = ys->next; | ||||||
|  |  | ||||||
|  | 	sALIAS = ys->old_salias; | ||||||
|  | 	herep = ys->old_herep; | ||||||
|  | 	reject = ys->old_reject; | ||||||
|  | 	symbol = ys->old_symbol; | ||||||
|  |  | ||||||
|  | 	subshell_nesting_type = ys->old_nesting_type; | ||||||
|  |  | ||||||
|  | 	afree(ys, ATEMP); | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user