diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-09-15 19:31:44 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-09-15 19:31:44 +0200 |
commit | 704c596563a5b4da4349b272d0c9c71aacea34a7 (patch) | |
tree | 126cb27fb1980deeedb76a6f2227eb1840f0d4d0 | |
parent | 3512ef801839feeb20d178776fff999e1da532fd (diff) | |
download | busybox-w32-704c596563a5b4da4349b272d0c9c71aacea34a7.tar.gz busybox-w32-704c596563a5b4da4349b272d0c9c71aacea34a7.tar.bz2 busybox-w32-704c596563a5b4da4349b272d0c9c71aacea34a7.zip |
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>
-rw-r--r-- | shell/ash.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/shell/ash.c b/shell/ash.c index b12b859d5..4bc4f55d0 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -2158,6 +2158,7 @@ static const struct { | |||
2158 | { VSTRFIXED|VTEXTFIXED , defoptindvar, getoptsreset }, | 2158 | { VSTRFIXED|VTEXTFIXED , defoptindvar, getoptsreset }, |
2159 | #endif | 2159 | #endif |
2160 | { VSTRFIXED|VTEXTFIXED , NULL /* inited to linenovar */, NULL }, | 2160 | { VSTRFIXED|VTEXTFIXED , NULL /* inited to linenovar */, NULL }, |
2161 | { VSTRFIXED|VTEXTFIXED , NULL /* inited to funcnamevar */, NULL }, | ||
2161 | #if ENABLE_ASH_RANDOM_SUPPORT | 2162 | #if ENABLE_ASH_RANDOM_SUPPORT |
2162 | { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM", change_random }, | 2163 | { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM", change_random }, |
2163 | #endif | 2164 | #endif |
@@ -2184,6 +2185,8 @@ struct globals_var { | |||
2184 | struct var varinit[ARRAY_SIZE(varinit_data)]; | 2185 | struct var varinit[ARRAY_SIZE(varinit_data)]; |
2185 | int lineno; | 2186 | int lineno; |
2186 | char linenovar[sizeof("LINENO=") + sizeof(int)*3]; | 2187 | char linenovar[sizeof("LINENO=") + sizeof(int)*3]; |
2188 | char funcnamevar[sizeof("FUNCNAME=") + 64]; | ||
2189 | char *funcname; | ||
2187 | unsigned trap_depth; | 2190 | unsigned trap_depth; |
2188 | bool in_trap_ERR; /* ERR cannot recurse, no need to be a counter */ | 2191 | bool in_trap_ERR; /* ERR cannot recurse, no need to be a counter */ |
2189 | }; | 2192 | }; |
@@ -2196,6 +2199,8 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var; | |||
2196 | #define varinit (G_var.varinit ) | 2199 | #define varinit (G_var.varinit ) |
2197 | #define lineno (G_var.lineno ) | 2200 | #define lineno (G_var.lineno ) |
2198 | #define linenovar (G_var.linenovar ) | 2201 | #define linenovar (G_var.linenovar ) |
2202 | #define funcnamevar (G_var.funcnamevar ) | ||
2203 | #define funcname (G_var.funcname ) | ||
2199 | #define trap_depth (G_var.trap_depth ) | 2204 | #define trap_depth (G_var.trap_depth ) |
2200 | #define in_trap_ERR (G_var.in_trap_ERR ) | 2205 | #define in_trap_ERR (G_var.in_trap_ERR ) |
2201 | #define vifs varinit[0] | 2206 | #define vifs varinit[0] |
@@ -2213,13 +2218,14 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var; | |||
2213 | #endif | 2218 | #endif |
2214 | #define VAR_OFFSET2 (VAR_OFFSET1 + ENABLE_ASH_GETOPTS) | 2219 | #define VAR_OFFSET2 (VAR_OFFSET1 + ENABLE_ASH_GETOPTS) |
2215 | #define vlineno varinit[VAR_OFFSET2 + 5] | 2220 | #define vlineno varinit[VAR_OFFSET2 + 5] |
2221 | #define vfuncname varinit[VAR_OFFSET2 + 6] | ||
2216 | #if ENABLE_ASH_RANDOM_SUPPORT | 2222 | #if ENABLE_ASH_RANDOM_SUPPORT |
2217 | # define vrandom varinit[VAR_OFFSET2 + 6] | 2223 | # define vrandom varinit[VAR_OFFSET2 + 7] |
2218 | #endif | 2224 | #endif |
2219 | #define VAR_OFFSET3 (VAR_OFFSET2 + ENABLE_ASH_RANDOM_SUPPORT) | 2225 | #define VAR_OFFSET3 (VAR_OFFSET2 + ENABLE_ASH_RANDOM_SUPPORT) |
2220 | #if BASH_EPOCH_VARS | 2226 | #if BASH_EPOCH_VARS |
2221 | # define vepochs varinit[VAR_OFFSET3 + 6] | 2227 | # define vepochs varinit[VAR_OFFSET3 + 7] |
2222 | # define vepochr varinit[VAR_OFFSET3 + 7] | 2228 | # define vepochr varinit[VAR_OFFSET3 + 8] |
2223 | #endif | 2229 | #endif |
2224 | #define INIT_G_var() do { \ | 2230 | #define INIT_G_var() do { \ |
2225 | unsigned i; \ | 2231 | unsigned i; \ |
@@ -2232,6 +2238,8 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var; | |||
2232 | } \ | 2238 | } \ |
2233 | strcpy(linenovar, "LINENO="); \ | 2239 | strcpy(linenovar, "LINENO="); \ |
2234 | vlineno.var_text = linenovar; \ | 2240 | vlineno.var_text = linenovar; \ |
2241 | strcpy(funcnamevar, "FUNCNAME="); \ | ||
2242 | vfuncname.var_text = funcnamevar; \ | ||
2235 | } while (0) | 2243 | } while (0) |
2236 | 2244 | ||
2237 | /* | 2245 | /* |
@@ -2371,6 +2379,9 @@ lookupvar(const char *name) | |||
2371 | if (!(v->flags & VUNSET)) { | 2379 | if (!(v->flags & VUNSET)) { |
2372 | if (v->var_text == linenovar) { | 2380 | if (v->var_text == linenovar) { |
2373 | fmtstr(linenovar+7, sizeof(linenovar)-7, "%d", lineno); | 2381 | fmtstr(linenovar+7, sizeof(linenovar)-7, "%d", lineno); |
2382 | } else | ||
2383 | if (v->var_text == funcnamevar) { | ||
2384 | safe_strncpy(funcnamevar+9, funcname ? funcname : "", sizeof(funcnamevar)-9); | ||
2374 | } | 2385 | } |
2375 | return var_end(v->var_text); | 2386 | return var_end(v->var_text); |
2376 | } | 2387 | } |
@@ -9875,6 +9886,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags) | |||
9875 | int e; | 9886 | int e; |
9876 | int savelineno; | 9887 | int savelineno; |
9877 | int savefuncline; | 9888 | int savefuncline; |
9889 | char *savefuncname; | ||
9878 | char *savetrap = NULL; | 9890 | char *savetrap = NULL; |
9879 | 9891 | ||
9880 | if (!Eflag) { | 9892 | if (!Eflag) { |
@@ -9884,6 +9896,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags) | |||
9884 | savelineno = lineno; | 9896 | savelineno = lineno; |
9885 | saveparam = shellparam; | 9897 | saveparam = shellparam; |
9886 | savefuncline = funcline; | 9898 | savefuncline = funcline; |
9899 | savefuncname = funcname; | ||
9887 | savehandler = exception_handler; | 9900 | savehandler = exception_handler; |
9888 | e = setjmp(jmploc.loc); | 9901 | e = setjmp(jmploc.loc); |
9889 | if (e) { | 9902 | if (e) { |
@@ -9893,6 +9906,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags) | |||
9893 | exception_handler = &jmploc; | 9906 | exception_handler = &jmploc; |
9894 | shellparam.malloced = 0; | 9907 | shellparam.malloced = 0; |
9895 | func->count++; | 9908 | func->count++; |
9909 | funcname = func->n.ndefun.text; | ||
9896 | funcline = func->n.ndefun.linno; | 9910 | funcline = func->n.ndefun.linno; |
9897 | INT_ON; | 9911 | INT_ON; |
9898 | shellparam.nparam = argc - 1; | 9912 | shellparam.nparam = argc - 1; |
@@ -9904,6 +9918,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags) | |||
9904 | evaltree(func->n.ndefun.body, flags & EV_TESTED); | 9918 | evaltree(func->n.ndefun.body, flags & EV_TESTED); |
9905 | funcdone: | 9919 | funcdone: |
9906 | INT_OFF; | 9920 | INT_OFF; |
9921 | funcname = savefuncname; | ||
9907 | if (savetrap) { | 9922 | if (savetrap) { |
9908 | if (!trap[NTRAP_ERR]) | 9923 | if (!trap[NTRAP_ERR]) |
9909 | trap[NTRAP_ERR] = savetrap; | 9924 | trap[NTRAP_ERR] = savetrap; |
@@ -13639,6 +13654,12 @@ exitcmd(int argc UNUSED_PARAM, char **argv) | |||
13639 | if (argv[1]) | 13654 | if (argv[1]) |
13640 | savestatus = number(argv[1]); | 13655 | savestatus = number(argv[1]); |
13641 | 13656 | ||
13657 | //TODO: this script | ||
13658 | // trap 'echo trap:$FUNCNAME' EXIT | ||
13659 | // f() { exit; } | ||
13660 | // f | ||
13661 | //prints "trap:f" in bash. We can call exitshell() here to achieve this. | ||
13662 | //For now, keeping dash code: | ||
13642 | raise_exception(EXEXIT); | 13663 | raise_exception(EXEXIT); |
13643 | /* NOTREACHED */ | 13664 | /* NOTREACHED */ |
13644 | } | 13665 | } |