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 },
|
{ VSTRFIXED|VTEXTFIXED , defoptindvar, getoptsreset },
|
||||||
#endif
|
#endif
|
||||||
{ VSTRFIXED|VTEXTFIXED , NULL /* inited to linenovar */, NULL },
|
{ VSTRFIXED|VTEXTFIXED , NULL /* inited to linenovar */, NULL },
|
||||||
|
{ VSTRFIXED|VTEXTFIXED , NULL /* inited to funcnamevar */, NULL },
|
||||||
#if ENABLE_ASH_RANDOM_SUPPORT
|
#if ENABLE_ASH_RANDOM_SUPPORT
|
||||||
{ VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM", change_random },
|
{ VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM", change_random },
|
||||||
#endif
|
#endif
|
||||||
@ -2184,6 +2185,8 @@ struct globals_var {
|
|||||||
struct var varinit[ARRAY_SIZE(varinit_data)];
|
struct var varinit[ARRAY_SIZE(varinit_data)];
|
||||||
int lineno;
|
int lineno;
|
||||||
char linenovar[sizeof("LINENO=") + sizeof(int)*3];
|
char linenovar[sizeof("LINENO=") + sizeof(int)*3];
|
||||||
|
char funcnamevar[sizeof("FUNCNAME=") + 64];
|
||||||
|
char *funcname;
|
||||||
unsigned trap_depth;
|
unsigned trap_depth;
|
||||||
bool in_trap_ERR; /* ERR cannot recurse, no need to be a counter */
|
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 varinit (G_var.varinit )
|
||||||
#define lineno (G_var.lineno )
|
#define lineno (G_var.lineno )
|
||||||
#define linenovar (G_var.linenovar )
|
#define linenovar (G_var.linenovar )
|
||||||
|
#define funcnamevar (G_var.funcnamevar )
|
||||||
|
#define funcname (G_var.funcname )
|
||||||
#define trap_depth (G_var.trap_depth )
|
#define trap_depth (G_var.trap_depth )
|
||||||
#define in_trap_ERR (G_var.in_trap_ERR )
|
#define in_trap_ERR (G_var.in_trap_ERR )
|
||||||
#define vifs varinit[0]
|
#define vifs varinit[0]
|
||||||
@ -2213,13 +2218,14 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var;
|
|||||||
#endif
|
#endif
|
||||||
#define VAR_OFFSET2 (VAR_OFFSET1 + ENABLE_ASH_GETOPTS)
|
#define VAR_OFFSET2 (VAR_OFFSET1 + ENABLE_ASH_GETOPTS)
|
||||||
#define vlineno varinit[VAR_OFFSET2 + 5]
|
#define vlineno varinit[VAR_OFFSET2 + 5]
|
||||||
|
#define vfuncname varinit[VAR_OFFSET2 + 6]
|
||||||
#if ENABLE_ASH_RANDOM_SUPPORT
|
#if ENABLE_ASH_RANDOM_SUPPORT
|
||||||
# define vrandom varinit[VAR_OFFSET2 + 6]
|
# define vrandom varinit[VAR_OFFSET2 + 7]
|
||||||
#endif
|
#endif
|
||||||
#define VAR_OFFSET3 (VAR_OFFSET2 + ENABLE_ASH_RANDOM_SUPPORT)
|
#define VAR_OFFSET3 (VAR_OFFSET2 + ENABLE_ASH_RANDOM_SUPPORT)
|
||||||
#if BASH_EPOCH_VARS
|
#if BASH_EPOCH_VARS
|
||||||
# define vepochs varinit[VAR_OFFSET3 + 6]
|
# define vepochs varinit[VAR_OFFSET3 + 7]
|
||||||
# define vepochr varinit[VAR_OFFSET3 + 7]
|
# define vepochr varinit[VAR_OFFSET3 + 8]
|
||||||
#endif
|
#endif
|
||||||
#define INIT_G_var() do { \
|
#define INIT_G_var() do { \
|
||||||
unsigned i; \
|
unsigned i; \
|
||||||
@ -2232,6 +2238,8 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var;
|
|||||||
} \
|
} \
|
||||||
strcpy(linenovar, "LINENO="); \
|
strcpy(linenovar, "LINENO="); \
|
||||||
vlineno.var_text = linenovar; \
|
vlineno.var_text = linenovar; \
|
||||||
|
strcpy(funcnamevar, "FUNCNAME="); \
|
||||||
|
vfuncname.var_text = funcnamevar; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2371,6 +2379,9 @@ lookupvar(const char *name)
|
|||||||
if (!(v->flags & VUNSET)) {
|
if (!(v->flags & VUNSET)) {
|
||||||
if (v->var_text == linenovar) {
|
if (v->var_text == linenovar) {
|
||||||
fmtstr(linenovar+7, sizeof(linenovar)-7, "%d", lineno);
|
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);
|
return var_end(v->var_text);
|
||||||
}
|
}
|
||||||
@ -9875,6 +9886,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags)
|
|||||||
int e;
|
int e;
|
||||||
int savelineno;
|
int savelineno;
|
||||||
int savefuncline;
|
int savefuncline;
|
||||||
|
char *savefuncname;
|
||||||
char *savetrap = NULL;
|
char *savetrap = NULL;
|
||||||
|
|
||||||
if (!Eflag) {
|
if (!Eflag) {
|
||||||
@ -9884,6 +9896,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags)
|
|||||||
savelineno = lineno;
|
savelineno = lineno;
|
||||||
saveparam = shellparam;
|
saveparam = shellparam;
|
||||||
savefuncline = funcline;
|
savefuncline = funcline;
|
||||||
|
savefuncname = funcname;
|
||||||
savehandler = exception_handler;
|
savehandler = exception_handler;
|
||||||
e = setjmp(jmploc.loc);
|
e = setjmp(jmploc.loc);
|
||||||
if (e) {
|
if (e) {
|
||||||
@ -9893,6 +9906,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags)
|
|||||||
exception_handler = &jmploc;
|
exception_handler = &jmploc;
|
||||||
shellparam.malloced = 0;
|
shellparam.malloced = 0;
|
||||||
func->count++;
|
func->count++;
|
||||||
|
funcname = func->n.ndefun.text;
|
||||||
funcline = func->n.ndefun.linno;
|
funcline = func->n.ndefun.linno;
|
||||||
INT_ON;
|
INT_ON;
|
||||||
shellparam.nparam = argc - 1;
|
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);
|
evaltree(func->n.ndefun.body, flags & EV_TESTED);
|
||||||
funcdone:
|
funcdone:
|
||||||
INT_OFF;
|
INT_OFF;
|
||||||
|
funcname = savefuncname;
|
||||||
if (savetrap) {
|
if (savetrap) {
|
||||||
if (!trap[NTRAP_ERR])
|
if (!trap[NTRAP_ERR])
|
||||||
trap[NTRAP_ERR] = savetrap;
|
trap[NTRAP_ERR] = savetrap;
|
||||||
@ -13639,6 +13654,12 @@ exitcmd(int argc UNUSED_PARAM, char **argv)
|
|||||||
if (argv[1])
|
if (argv[1])
|
||||||
savestatus = number(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);
|
raise_exception(EXEXIT);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user