ash: introduce bash-like $FUNCNAME
Patch adapted from Roberto A. Foglietta <roberto.foglietta@gmail.com> work. function old new delta lookupvar 106 150 +44 evalfun 369 408 +39 ash_main 1218 1242 +24 varinit_data 156 168 +12 .rodata 104162 104172 +10 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 5/0 up/down: 129/0) Total: 129 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
		
							
								
								
									
										27
									
								
								shell/ash.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								shell/ash.c
									
									
									
									
									
								
							| @@ -2158,6 +2158,7 @@ static const struct { | ||||
| 	{ VSTRFIXED|VTEXTFIXED       , defoptindvar, getoptsreset    }, | ||||
| #endif | ||||
| 	{ VSTRFIXED|VTEXTFIXED       , NULL /* inited to linenovar */, NULL }, | ||||
| 	{ VSTRFIXED|VTEXTFIXED       , NULL /* inited to funcnamevar */, NULL }, | ||||
| #if ENABLE_ASH_RANDOM_SUPPORT | ||||
| 	{ VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM", change_random }, | ||||
| #endif | ||||
| @@ -2184,6 +2185,8 @@ struct globals_var { | ||||
| 	struct var varinit[ARRAY_SIZE(varinit_data)]; | ||||
| 	int lineno; | ||||
| 	char linenovar[sizeof("LINENO=") + sizeof(int)*3]; | ||||
| 	char funcnamevar[sizeof("FUNCNAME=") + 64]; | ||||
| 	char *funcname; | ||||
| 	unsigned trap_depth; | ||||
| 	bool in_trap_ERR; /* ERR cannot recurse, no need to be a counter */ | ||||
| }; | ||||
| @@ -2196,6 +2199,8 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var; | ||||
| #define varinit       (G_var.varinit      ) | ||||
| #define lineno        (G_var.lineno       ) | ||||
| #define linenovar     (G_var.linenovar    ) | ||||
| #define funcnamevar   (G_var.funcnamevar  ) | ||||
| #define funcname      (G_var.funcname     ) | ||||
| #define trap_depth    (G_var.trap_depth   ) | ||||
| #define in_trap_ERR   (G_var.in_trap_ERR  ) | ||||
| #define vifs      varinit[0] | ||||
| @@ -2213,13 +2218,14 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var; | ||||
| #endif | ||||
| #define VAR_OFFSET2 (VAR_OFFSET1 + ENABLE_ASH_GETOPTS) | ||||
| #define vlineno   varinit[VAR_OFFSET2 + 5] | ||||
| #define vfuncname varinit[VAR_OFFSET2 + 6] | ||||
| #if ENABLE_ASH_RANDOM_SUPPORT | ||||
| # define vrandom  varinit[VAR_OFFSET2 + 6] | ||||
| # define vrandom  varinit[VAR_OFFSET2 + 7] | ||||
| #endif | ||||
| #define VAR_OFFSET3 (VAR_OFFSET2 + ENABLE_ASH_RANDOM_SUPPORT) | ||||
| #if BASH_EPOCH_VARS | ||||
| # define vepochs  varinit[VAR_OFFSET3 + 6] | ||||
| # define vepochr  varinit[VAR_OFFSET3 + 7] | ||||
| # define vepochs  varinit[VAR_OFFSET3 + 7] | ||||
| # define vepochr  varinit[VAR_OFFSET3 + 8] | ||||
| #endif | ||||
| #define INIT_G_var() do { \ | ||||
| 	unsigned i; \ | ||||
| @@ -2232,6 +2238,8 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var; | ||||
| 	} \ | ||||
| 	strcpy(linenovar, "LINENO="); \ | ||||
| 	vlineno.var_text = linenovar; \ | ||||
| 	strcpy(funcnamevar, "FUNCNAME="); \ | ||||
| 	vfuncname.var_text = funcnamevar; \ | ||||
| } while (0) | ||||
|  | ||||
| /* | ||||
| @@ -2371,6 +2379,9 @@ lookupvar(const char *name) | ||||
| 		if (!(v->flags & VUNSET)) { | ||||
| 			if (v->var_text == linenovar) { | ||||
| 				fmtstr(linenovar+7, sizeof(linenovar)-7, "%d", lineno); | ||||
| 			} else | ||||
| 			if (v->var_text == funcnamevar) { | ||||
| 				safe_strncpy(funcnamevar+9, funcname ? funcname : "", sizeof(funcnamevar)-9); | ||||
| 			} | ||||
| 			return var_end(v->var_text); | ||||
| 		} | ||||
| @@ -9875,6 +9886,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags) | ||||
| 	int e; | ||||
| 	int savelineno; | ||||
| 	int savefuncline; | ||||
| 	char *savefuncname; | ||||
| 	char *savetrap = NULL; | ||||
|  | ||||
| 	if (!Eflag) { | ||||
| @@ -9884,6 +9896,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags) | ||||
| 	savelineno = lineno; | ||||
| 	saveparam = shellparam; | ||||
| 	savefuncline = funcline; | ||||
| 	savefuncname = funcname; | ||||
| 	savehandler = exception_handler; | ||||
| 	e = setjmp(jmploc.loc); | ||||
| 	if (e) { | ||||
| @@ -9893,6 +9906,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags) | ||||
| 	exception_handler = &jmploc; | ||||
| 	shellparam.malloced = 0; | ||||
| 	func->count++; | ||||
| 	funcname = func->n.ndefun.text; | ||||
| 	funcline = func->n.ndefun.linno; | ||||
| 	INT_ON; | ||||
| 	shellparam.nparam = argc - 1; | ||||
| @@ -9904,6 +9918,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags) | ||||
| 	evaltree(func->n.ndefun.body, flags & EV_TESTED); | ||||
|  funcdone: | ||||
| 	INT_OFF; | ||||
| 	funcname = savefuncname; | ||||
| 	if (savetrap) { | ||||
| 		if (!trap[NTRAP_ERR]) | ||||
| 			trap[NTRAP_ERR] = savetrap; | ||||
| @@ -13639,6 +13654,12 @@ exitcmd(int argc UNUSED_PARAM, char **argv) | ||||
| 	if (argv[1]) | ||||
| 		savestatus = number(argv[1]); | ||||
|  | ||||
| //TODO: this script | ||||
| // trap 'echo trap:$FUNCNAME' EXIT | ||||
| // f() { exit; } | ||||
| // f | ||||
| //prints "trap:f" in bash. We can call exitshell() here to achieve this. | ||||
| //For now, keeping dash code: | ||||
| 	raise_exception(EXEXIT); | ||||
| 	/* NOTREACHED */ | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user