ash: introduce bash-like $FUNCNAME
No binary (build failed)
—
(log yok)
| @@ -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 */ | |
| } | |