diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-09-13 14:56:10 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-09-13 14:56:10 +0900 |
commit | c90fa15cbf2fc4380c58ff1b32f31d9ad6f57f81 (patch) | |
tree | 6550151487ff940dc98a5bc77cfd8ab2f1f387b5 | |
parent | 8d39e6d71933b767be25ad1af9b0e7811b68d887 (diff) | |
download | dash-c90fa15cbf2fc4380c58ff1b32f31d9ad6f57f81.tar.gz dash-c90fa15cbf2fc4380c58ff1b32f31d9ad6f57f81.tar.bz2 dash-c90fa15cbf2fc4380c58ff1b32f31d9ad6f57f81.zip |
Imported Upstream version 0.5.9.1upstream/0.5.9.1
Change-Id: I7e95f2313b69beadd45cc22a87e973301c191774
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
-rwxr-xr-x | configure | 20 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/Makefile.in | 4 | ||||
-rw-r--r-- | src/bltin/printf.c | 25 | ||||
-rw-r--r-- | src/dash.1 | 5 | ||||
-rw-r--r-- | src/eval.c | 140 | ||||
-rw-r--r-- | src/eval.h | 2 | ||||
-rw-r--r-- | src/expand.c | 116 | ||||
-rw-r--r-- | src/expand.h | 2 | ||||
-rw-r--r-- | src/jobs.c | 10 | ||||
-rw-r--r-- | src/main.c | 7 | ||||
-rw-r--r-- | src/miscbltin.c | 30 | ||||
-rw-r--r-- | src/mkbuiltins | 12 | ||||
-rw-r--r-- | src/trap.c | 25 |
15 files changed, 235 insertions, 169 deletions
@@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for dash 0.5.9. +# Generated by GNU Autoconf 2.69 for dash 0.5.9.1. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -577,8 +577,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='dash' PACKAGE_TARNAME='dash' -PACKAGE_VERSION='0.5.9' -PACKAGE_STRING='dash 0.5.9' +PACKAGE_VERSION='0.5.9.1' +PACKAGE_STRING='dash 0.5.9.1' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1269,7 +1269,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures dash 0.5.9 to adapt to many kinds of systems. +\`configure' configures dash 0.5.9.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1335,7 +1335,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of dash 0.5.9:";; + short | recursive ) echo "Configuration of dash 0.5.9.1:";; esac cat <<\_ACEOF @@ -1440,7 +1440,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -dash configure 0.5.9 +dash configure 0.5.9.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2034,7 +2034,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by dash $as_me 0.5.9, which was +It was created by dash $as_me 0.5.9.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2849,7 +2849,7 @@ fi # Define the identity of the package. PACKAGE='dash' - VERSION='0.5.9' + VERSION='0.5.9.1' cat >>confdefs.h <<_ACEOF @@ -5313,7 +5313,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by dash $as_me 0.5.9, which was +This file was extended by dash $as_me 0.5.9.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5379,7 +5379,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -dash config.status 0.5.9 +dash config.status 0.5.9.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 4c2c179..9c4ced8 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(dash, 0.5.9) +AC_INIT(dash, 0.5.9.1) AM_INIT_AUTOMAKE([foreign]) AC_CONFIG_SRCDIR([src/main.c]) diff --git a/src/Makefile.am b/src/Makefile.am index 120ffa2..139355e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,13 +46,13 @@ EXTRA_DIST = \ mknodes.c nodetypes nodes.c.pat mksyntax.c mksignames.c token.h token_vars.h: mktokens - sh $^ + $(SHELL) $^ builtins.def: builtins.def.in $(top_builddir)/config.h $(COMPILE) -E -x c -o $@ $< builtins.c builtins.h: mkbuiltins builtins.def - sh $^ + $(SHELL) $^ init.c: mkinit $(dash_CFILES) ./$^ diff --git a/src/Makefile.in b/src/Makefile.in index 4ccb12c..0bd9ad1 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -691,13 +691,13 @@ uninstall-man: uninstall-man1 token.h token_vars.h: mktokens - sh $^ + $(SHELL) $^ builtins.def: builtins.def.in $(top_builddir)/config.h $(COMPILE) -E -x c -o $@ $< builtins.c builtins.h: mkbuiltins builtins.def - sh $^ + $(SHELL) $^ init.c: mkinit $(dash_CFILES) ./$^ diff --git a/src/bltin/printf.c b/src/bltin/printf.c index 9673e10..a626cee 100644 --- a/src/bltin/printf.c +++ b/src/bltin/printf.c @@ -175,17 +175,24 @@ pc: /* skip to field width */ fmt += strspn(fmt, SKIP1); - if (*fmt == '*') - *param++ = getuintmax(1); - - /* skip to possible '.', get following precision */ - fmt += strspn(fmt, SKIP2); - if (*fmt == '.') + if (*fmt == '*') { ++fmt; - if (*fmt == '*') *param++ = getuintmax(1); + } else { + /* skip to possible '.', + * get following precision + */ + fmt += strspn(fmt, SKIP2); + } - fmt += strspn(fmt, SKIP2); + if (*fmt == '.') { + ++fmt; + if (*fmt == '*') { + ++fmt; + *param++ = getuintmax(1); + } else + fmt += strspn(fmt, SKIP2); + } ch = *fmt; if (!ch) @@ -452,7 +459,7 @@ echocmd(int argc, char **argv) if (likely(*argv)) nonl += print_escape_str("%s", NULL, NULL, *argv++); - if (nonl > 0) + if (likely((nonl + !*argv) > 1)) break; c = *argv ? ' ' : '\n'; @@ -2114,7 +2114,7 @@ printed; for commands and tracked aliases the complete pathname of the command is printed. .It ulimit Xo .Op Fl H \*(Ba Fl S -.Op Fl a \*(Ba Fl tfdscmlpn Op Ar value +.Op Fl a \*(Ba Fl tfdscmlpnv Op Ar value .Xc Inquire about or set the hard or soft limits on processes or set new limits. @@ -2164,6 +2164,9 @@ show or set the limit on the number of processes this user can have at one time .It Fl n show or set the limit on the number files a process can have open at once +.It Fl v +show or set the limit on the total virtual memory that can be +in use by a process (in kilobytes) .It Fl r show or set the limit on the real-time scheduling priority of a process .El @@ -81,16 +81,16 @@ int savestatus = -1; /* exit status of last command outside traps */ STATIC #endif void evaltreenr(union node *, int) __attribute__ ((__noreturn__)); -STATIC void evalloop(union node *, int); -STATIC void evalfor(union node *, int); -STATIC void evalcase(union node *, int); -STATIC void evalsubshell(union node *, int); +STATIC int evalloop(union node *, int); +STATIC int evalfor(union node *, int); +STATIC int evalcase(union node *, int); +STATIC int evalsubshell(union node *, int); STATIC void expredir(union node *); -STATIC void evalpipe(union node *, int); +STATIC int evalpipe(union node *, int); #ifdef notyet -STATIC void evalcommand(union node *, int, struct backcmd *); +STATIC int evalcommand(union node *, int, struct backcmd *); #else -STATIC void evalcommand(union node *, int); +STATIC int evalcommand(union node *, int); #endif STATIC int evalbltin(const struct builtincmd *, int, char **, int); STATIC int evalfun(struct funcnode *, int, char **, int); @@ -170,10 +170,13 @@ evalstring(char *s, int flags) setstackmark(&smark); status = 0; - while ((n = parsecmd(0)) != NEOF) { - evaltree(n, flags & ~(parser_eof() ? 0 : EV_EXIT)); - status = exitstatus; - popstackmark(&smark); + for (; (n = parsecmd(0)) != NEOF; popstackmark(&smark)) { + int i; + + i = evaltree(n, flags & ~(parser_eof() ? 0 : EV_EXIT)); + if (n) + status = i; + if (evalskip) break; } @@ -191,13 +194,13 @@ evalstring(char *s, int flags) * exitstatus. */ -void +int evaltree(union node *n, int flags) { int checkexit = 0; - void (*evalfn)(union node *, int); + int (*evalfn)(union node *, int); unsigned isor; - int status; + int status = 0; if (n == NULL) { TRACE(("evaltree(NULL) called\n")); goto out; @@ -220,8 +223,7 @@ evaltree(union node *n, int flags) break; #endif case NNOT: - evaltree(n->nnot.com, EV_TESTED); - status = !exitstatus; + status = !evaltree(n->nnot.com, EV_TESTED); goto setstatus; case NREDIR: errlinno = lineno = n->nredir.linno; @@ -229,11 +231,8 @@ evaltree(union node *n, int flags) lineno -= funcline - 1; expredir(n->nredir.redirect); pushredir(n->nredir.redirect); - status = redirectsafe(n->nredir.redirect, REDIR_PUSH); - if (!status) { - evaltree(n->nredir.n, flags & EV_TESTED); - status = exitstatus; - } + status = redirectsafe(n->nredir.redirect, REDIR_PUSH) ?: + evaltree(n->nredir.n, flags & EV_TESTED); if (n->nredir.redirect) popredir(0); goto setstatus; @@ -241,8 +240,8 @@ evaltree(union node *n, int flags) #ifdef notyet if (eflag && !(flags & EV_TESTED)) checkexit = ~0; - evalcommand(n, flags, (struct backcmd *)NULL); - break; + status = evalcommand(n, flags, (struct backcmd *)NULL); + goto setstatus; #else evalfn = evalcommand; checkexit: @@ -277,43 +276,37 @@ checkexit: #error NOR + 1 != NSEMI #endif isor = n->type - NAND; - evaltree( - n->nbinary.ch1, - (flags | ((isor >> 1) - 1)) & EV_TESTED - ); - if (!exitstatus == isor) + status = evaltree(n->nbinary.ch1, + (flags | ((isor >> 1) - 1)) & EV_TESTED); + if (!status == isor || evalskip) break; - if (!evalskip) { - n = n->nbinary.ch2; + n = n->nbinary.ch2; evaln: - evalfn = evaltree; + evalfn = evaltree; calleval: - evalfn(n, flags); - break; - } - break; + status = evalfn(n, flags); + goto setstatus; case NIF: - evaltree(n->nif.test, EV_TESTED); + status = evaltree(n->nif.test, EV_TESTED); if (evalskip) break; - if (exitstatus == 0) { + if (!status) { n = n->nif.ifpart; goto evaln; } else if (n->nif.elsepart) { n = n->nif.elsepart; goto evaln; } - goto success; + status = 0; + goto setstatus; case NDEFUN: defun(n); -success: - status = 0; setstatus: exitstatus = status; break; } out: - if (checkexit & exitstatus) + if (checkexit & status) goto exexit; dotrap(); @@ -322,6 +315,8 @@ out: exexit: exraise(EXEXIT); } + + return exitstatus; } @@ -362,7 +357,7 @@ static int skiploop(void) } -STATIC void +STATIC int evalloop(union node *n, int flags) { int skip; @@ -374,33 +369,34 @@ evalloop(union node *n, int flags) do { int i; - evaltree(n->nbinary.ch1, EV_TESTED); + i = evaltree(n->nbinary.ch1, EV_TESTED); skip = skiploop(); + if (skip == SKIPFUNC) + status = i; if (skip) continue; - i = exitstatus; if (n->type != NWHILE) i = !i; if (i != 0) break; - evaltree(n->nbinary.ch2, flags); - status = exitstatus; + status = evaltree(n->nbinary.ch2, flags); skip = skiploop(); } while (!(skip & ~SKIPCONT)); - if (skip != SKIPFUNC) - exitstatus = status; loopnest--; + + return status; } -STATIC void +STATIC int evalfor(union node *n, int flags) { struct arglist arglist; union node *argp; struct strlist *sp; struct stackmark smark; + int status; errlinno = lineno = n->nfor.linno; if (funcline) @@ -413,28 +409,31 @@ evalfor(union node *n, int flags) } *arglist.lastp = NULL; - exitstatus = 0; + status = 0; loopnest++; flags &= EV_TESTED; for (sp = arglist.list ; sp ; sp = sp->next) { setvar(n->nfor.var, sp->text, 0); - evaltree(n->nfor.body, flags); + status = evaltree(n->nfor.body, flags); if (skiploop() & ~SKIPCONT) break; } loopnest--; popstackmark(&smark); + + return status; } -STATIC void +STATIC int evalcase(union node *n, int flags) { union node *cp; union node *patp; struct arglist arglist; struct stackmark smark; + int status = 0; errlinno = lineno = n->ncase.linno; if (funcline) @@ -443,12 +442,16 @@ evalcase(union node *n, int flags) setstackmark(&smark); arglist.lastp = &arglist.list; expandarg(n->ncase.expr, &arglist, EXP_TILDE); - exitstatus = 0; for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) { for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) { if (casematch(patp, arglist.list->text)) { - if (evalskip == 0) { - evaltree(cp->nclist.body, flags); + /* Ensure body is non-empty as otherwise + * EV_EXIT may prevent us from setting the + * exit status. + */ + if (evalskip == 0 && cp->nclist.body) { + status = evaltree(cp->nclist.body, + flags); } goto out; } @@ -456,6 +459,8 @@ evalcase(union node *n, int flags) } out: popstackmark(&smark); + + return status; } @@ -464,7 +469,7 @@ out: * Kick off a subshell to evaluate a tree. */ -STATIC void +STATIC int evalsubshell(union node *n, int flags) { struct job *jp; @@ -493,8 +498,8 @@ nofork: status = 0; if (! backgnd) status = waitforjob(jp); - exitstatus = status; INTON; + return status; } @@ -540,7 +545,7 @@ expredir(union node *n) * of all the rest.) */ -STATIC void +STATIC int evalpipe(union node *n, int flags) { struct job *jp; @@ -548,6 +553,7 @@ evalpipe(union node *n, int flags) int pipelen; int prevfd; int pip[2]; + int status = 0; TRACE(("evalpipe(0x%lx) called\n", (long)n)); pipelen = 0; @@ -588,10 +594,12 @@ evalpipe(union node *n, int flags) close(pip[1]); } if (n->npipe.backgnd == 0) { - exitstatus = waitforjob(jp); - TRACE(("evalpipe: job done exit status %d\n", exitstatus)); + status = waitforjob(jp); + TRACE(("evalpipe: job done exit status %d\n", status)); } INTON; + + return status; } @@ -678,7 +686,7 @@ parse_command_args(char **argv, const char **path) * Execute a simple command. */ -STATIC void +STATIC int #ifdef notyet evalcommand(union node *cmd, int flags, struct backcmd *backcmd) #else @@ -848,7 +856,7 @@ bail: INTOFF; jp = makejob(cmd, 1); if (forkshell(jp, cmd, FORK_FG) != 0) { - exitstatus = waitforjob(jp); + status = waitforjob(jp); INTON; break; } @@ -867,17 +875,19 @@ bail: if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) { if (exception == EXERROR && spclbltin <= 0) { FORCEINTON; - break; + goto readstatus; } raise: longjmp(handler->loc, 1); } - break; + goto readstatus; case CMDFUNCTION: poplocalvars(1); if (evalfun(cmdentry.u.func, argc, argv, flags)) goto raise; +readstatus: + status = exitstatus; break; } @@ -893,6 +903,8 @@ out: */ setvar("_", lastarg, 0); popstackmark(&smark); + + return status; } STATIC int @@ -53,7 +53,7 @@ struct backcmd { /* result of evalbackcmd */ int evalstring(char *, int); union node; /* BLETCH for ansi C */ -void evaltree(union node *, int); +int evaltree(union node *, int); void evalbackcmd(union node *, struct backcmd *); extern int evalskip; diff --git a/src/expand.c b/src/expand.c index b2d710d..2a50830 100644 --- a/src/expand.c +++ b/src/expand.c @@ -50,6 +50,7 @@ #include <glob.h> #endif #include <ctype.h> +#include <stdbool.h> /* * Routines to expand arguments to commands. We have to deal with @@ -203,7 +204,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag) * TODO - EXP_REDIR */ if (flag & EXP_FULL) { - ifsbreakup(p, &exparg); + ifsbreakup(p, -1, &exparg); *exparg.lastp = NULL; exparg.lastp = &exparg.list; expandmeta(exparg.list, flag); @@ -1016,15 +1017,18 @@ recordregion(int start, int end, int nulonly) * Break the argument string into pieces based upon IFS and add the * strings to the argument list. The regions of the string to be * searched for IFS characters have been stored by recordregion. + * If maxargs is non-negative, at most maxargs arguments will be created, by + * joining together the last arguments. */ void -ifsbreakup(char *string, struct arglist *arglist) +ifsbreakup(char *string, int maxargs, struct arglist *arglist) { struct ifsregion *ifsp; struct strlist *sp; char *start; char *p; char *q; + char *r = NULL; const char *ifs, *realifs; int ifsspc; int nulonly; @@ -1042,16 +1046,76 @@ ifsbreakup(char *string, struct arglist *arglist) ifs = nulonly ? nullstr : realifs; ifsspc = 0; while (p < string + ifsp->endoff) { + int c; + bool isifs; + bool isdefifs; + q = p; - if (*p == (char)CTLESC) - p++; - if (strchr(ifs, *p)) { + c = *p++; + if (c == (char)CTLESC) + c = *p++; + + isifs = strchr(ifs, c); + isdefifs = false; + if (isifs) + isdefifs = strchr(defifs, c); + + /* If only reading one more argument: + * If we have exactly one field, + * read that field without its terminator. + * If we have more than one field, + * read all fields including their terminators, + * except for trailing IFS whitespace. + * + * This means that if we have only IFS + * characters left, and at most one + * of them is non-whitespace, we stop + * reading here. + * Otherwise, we read all the remaining + * characters except for trailing + * IFS whitespace. + * + * In any case, r indicates the start + * of the characters to remove, or NULL + * if no characters should be removed. + */ + if (!maxargs) { + if (isdefifs) { + if (!r) + r = q; + continue; + } + + if (!(isifs && ifsspc)) + r = NULL; + + ifsspc = 0; + continue; + } + + if (ifsspc) { + if (isifs) + q = p; + + start = q; + + if (isdefifs) + continue; + + isifs = false; + } + + if (isifs) { if (!nulonly) - ifsspc = (strchr(defifs, *p) != NULL); + ifsspc = isdefifs; /* Ignore IFS whitespace at start */ if (q == start && ifsspc) { - p++; start = p; + ifsspc = 0; + continue; + } + if (maxargs > 0 && !--maxargs) { + r = q; continue; } *q = '\0'; @@ -1059,39 +1123,20 @@ ifsbreakup(char *string, struct arglist *arglist) sp->text = start; *arglist->lastp = sp; arglist->lastp = &sp->next; - p++; - if (!nulonly) { - for (;;) { - if (p >= string + ifsp->endoff) { - break; - } - q = p; - if (*p == (char)CTLESC) - p++; - if (strchr(ifs, *p) == NULL ) { - p = q; - break; - } else if (strchr(defifs, *p) == NULL) { - if (ifsspc) { - p++; - ifsspc = 0; - } else { - p = q; - break; - } - } else - p++; - } - } start = p; - } else - p++; + continue; + } + + ifsspc = 0; } } while ((ifsp = ifsp->next) != NULL); if (nulonly) goto add; } + if (r) + *r = '\0'; + if (!*start) return; @@ -1539,14 +1584,14 @@ pmatch(const char *pattern, const char *string) p++; } found = 0; - chr = *q++; + chr = *q; if (chr == '\0') return 0; c = *p++; do { if (!c) { p = startp; - c = *p; + c = '['; goto dft; } if (c == '[') { @@ -1573,6 +1618,7 @@ pmatch(const char *pattern, const char *string) } while ((c = *p++) != ']'); if (found == invert) return 0; + q++; break; } dft: default: diff --git a/src/expand.h b/src/expand.h index 6a90f67..26dc5b4 100644 --- a/src/expand.h +++ b/src/expand.h @@ -69,7 +69,7 @@ char *_rmescapes(char *, int); int casematch(union node *, char *); void recordregion(int, int, int); void removerecordregions(int); -void ifsbreakup(char *, struct arglist *); +void ifsbreakup(char *, int, struct arglist *); void ifsfree(void); /* From arith.y */ @@ -699,7 +699,7 @@ check: if (is_number(p)) { num = atoi(p); - if (num <= njobs) { + if (num > 0 && num <= njobs) { jp = jobtab + num - 1; if (jp->used) goto gotit; @@ -714,9 +714,7 @@ check: } found = 0; - while (1) { - if (!jp) - goto err; + while (jp) { if (match(jp->ps[0].cmd, p)) { if (found) goto err; @@ -726,6 +724,10 @@ check: jp = jp->prev_job; } + if (!found) + goto err; + jp = found; + gotit: #if JOBS err_msg = "job %s not created under job control"; @@ -225,10 +225,13 @@ cmdloop(int top) } numeof++; } else if (nflag == 0) { + int i; + job_warning = (job_warning == 2) ? 1 : 0; numeof = 0; - evaltree(n, 0); - status = exitstatus; + i = evaltree(n, 0); + if (n) + status = i; } popstackmark(&smark); diff --git a/src/miscbltin.c b/src/miscbltin.c index b596fd2..39b9c47 100644 --- a/src/miscbltin.c +++ b/src/miscbltin.c @@ -67,28 +67,21 @@ * less fields than variables -> remaining variables unset. * * @param line complete line of input + * @param ac argument count * @param ap argument (variable) list * @param len length of line including trailing '\0' */ static void -readcmd_handle_line(char *s, char **ap) +readcmd_handle_line(char *s, int ac, char **ap) { struct arglist arglist; struct strlist *sl; - char *backup; - char *line; - /* ifsbreakup will fiddle with stack region... */ - line = stackblock(); s = grabstackstr(s); - /* need a copy, so that delimiters aren't lost - * in case there are more fields than variables */ - backup = sstrdup(line); - arglist.lastp = &arglist.list; - ifsbreakup(s, &arglist); + ifsbreakup(s, ac, &arglist); *arglist.lastp = NULL; ifsfree(); @@ -104,21 +97,6 @@ readcmd_handle_line(char *s, char **ap) return; } - /* remaining fields present, but no variables left. */ - if (!ap[1] && sl->next) { - size_t offset; - char *remainder; - - /* FIXME little bit hacky, assuming that ifsbreakup - * will not modify the length of the string */ - offset = sl->text - s; - remainder = backup + offset; - rmescapes(remainder); - setvar(*ap, remainder, 0); - - return; - } - /* set variable to field */ rmescapes(sl->text); setvar(*ap, sl->text, 0); @@ -211,7 +189,7 @@ start: out: recordregion(startloc, p - (char *)stackblock(), 0); STACKSTRNUL(p); - readcmd_handle_line(p + 1, ap); + readcmd_handle_line(p + 1, argc - (ap - argv), ap); return status; } diff --git a/src/mkbuiltins b/src/mkbuiltins index 8c74d6b..b4d6f4e 100644 --- a/src/mkbuiltins +++ b/src/mkbuiltins @@ -84,9 +84,13 @@ awk '{ for (i = 2 ; i <= NF ; i++) { opt = substr($2, 2) $2 = $3 } - printf "\t{ \"%s\", %s, %d },\n", $1, - (opt ~ /n/) ? "NULL" : $2, - (opt ~ /s/) + (opt ~ /[su]/) * 2 + (opt ~ /a/) * 4 + mask = 0 + cmd = $2 + if (opt ~ /n/) { cmd = "NULL" } + if (opt ~ /s/) { mask += 1 } + if (opt ~ /[su]/) { mask += 2 } + if (opt ~ /a/) { mask += 4 } + printf "\t{ \"%s\", %s, %d },\n", $1, cmd, mask }' echo '};' @@ -97,7 +101,7 @@ cat <<\! */ ! -sed 's/ -[a-z]*//' $temp2 | nl -b a -v 0 | +sed 's/ -[a-z]*//' $temp2 | nl -ba -v0 | LC_ALL= LC_COLLATE=C sort -u -k 3,3 | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | awk '{ printf "#define %s (builtincmd + %d)\n", $3, $1}' @@ -79,6 +79,8 @@ int gotsigchld; extern char *signal_names[]; +static int decode_signum(const char *); + #ifdef mkinit INCLUDE "trap.h" INIT { @@ -112,7 +114,7 @@ trapcmd(int argc, char **argv) } return 0; } - if (!ap[1]) + if (!ap[1] || decode_signum(*ap) >= 0) action = NULL; else action = *ap++; @@ -400,18 +402,27 @@ out: /* NOTREACHED */ } -int decode_signal(const char *string, int minsig) +static int decode_signum(const char *string) { - int signo; + int signo = -1; if (is_number(string)) { signo = atoi(string); - if (signo >= NSIG) { - return -1; - } - return signo; + if (signo >= NSIG) + signo = -1; } + return signo; +} + +int decode_signal(const char *string, int minsig) +{ + int signo; + + signo = decode_signum(string); + if (signo >= 0) + return signo; + for (signo = minsig; signo < NSIG; signo++) { if (!strcasecmp(string, signal_names[signo])) { return signo; |