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:
parent
3512ef8018
commit
704c596563
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 */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user