improve string pooling: saves 316 bytes in .text

This commit is contained in:
tg
2010-08-28 18:50:58 +00:00
parent d09fd67299
commit 3747722db4
14 changed files with 228 additions and 199 deletions

139
funcs.c
View File

@ -25,7 +25,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.158 2010/08/28 17:21:44 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.159 2010/08/28 18:50:51 tg Exp $");
#if HAVE_KILLPG
/*
@ -59,14 +59,14 @@ const struct builtin mkshbuiltins[] = {
{"*=:", c_label},
{"[", c_test},
{"*=break", c_brkcont},
{"=builtin", c_builtin},
{T_gbuiltin, c_builtin},
{"*=continue", c_brkcont},
{"*=eval", c_eval},
{"*=exec", c_exec},
{"*=exit", c_exitreturn},
{"+false", c_label},
{"*=return", c_exitreturn},
{"*=set", c_set},
{T_sgset, c_set},
{"*=shift", c_shift},
{"=times", c_times},
{"*=trap", c_trap},
@ -77,7 +77,7 @@ const struct builtin mkshbuiltins[] = {
{"ulimit", c_ulimit},
{"+umask", c_umask},
{"*=unset", c_unset},
{"+alias", c_alias}, /* no =: AT&T manual wrong */
{T_palias, c_alias}, /* no =: AT&T manual wrong */
{"+cd", c_cd},
{"chdir", c_cd}, /* dash compatibility hack */
{"+command", c_command},
@ -95,7 +95,7 @@ const struct builtin mkshbuiltins[] = {
{"pwd", c_pwd},
{"*=readonly", c_typeset},
{T__typeset, c_typeset},
{"+unalias", c_unalias},
{T_punalias, c_unalias},
{"whence", c_whence},
#ifndef MKSH_UNEMPLOYED
{"+bg", c_fgbg},
@ -447,9 +447,9 @@ c_cd(const char **wp)
if (rv < 0) {
if (cdnode)
bi_errorf("%s: bad directory", dir);
bi_errorf("%s: %s", dir, "bad directory");
else
bi_errorf("%s - %s", tryp, strerror(errno));
bi_errorf("%s: %s", tryp, strerror(errno));
afree(allocd, ATEMP);
return (1);
}
@ -521,7 +521,7 @@ c_pwd(const char **wp)
if (p && access(p, R_OK) < 0)
p = NULL;
if (!p && !(p = allocd = ksh_get_wd(NULL))) {
bi_errorf("can't get current directory - %s", strerror(errno));
bi_errorf("%s: %s", "can't get current directory", strerror(errno));
return (1);
}
shprintf("%s\n", p);
@ -613,7 +613,7 @@ c_print(const char **wp)
break;
case 'p':
if ((fd = coproc_getfd(W_OK, &emsg)) < 0) {
bi_errorf("-p: %s", emsg);
bi_errorf("%s: %s", "-p", emsg);
return (1);
}
break;
@ -627,7 +627,7 @@ c_print(const char **wp)
if (!*(s = builtin_opt.optarg))
fd = 0;
else if ((fd = check_fd(s, W_OK, &emsg)) < 0) {
bi_errorf("-u: %s: %s", s, emsg);
bi_errorf("%s: %s: %s", "-u", s, emsg);
return (1);
}
break;
@ -796,22 +796,32 @@ c_whence(const char **wp)
if (vflag || (tp->type != CALIAS && tp->type != CEXEC &&
tp->type != CTALIAS))
shf_puts(id, shl_stdout);
if (vflag)
switch (tp->type) {
case CKEYWD:
case CALIAS:
case CFUNC:
case CSHELL:
shf_puts(" is a", shl_stdout);
break;
}
switch (tp->type) {
case CKEYWD:
if (vflag)
shf_puts(" is a reserved word", shl_stdout);
shf_puts(" reserved word", shl_stdout);
break;
case CALIAS:
if (vflag)
shprintf(" is an %salias for ",
(tp->flag & EXPORT) ? "exported " : null);
shprintf("n %s%s for ",
(tp->flag & EXPORT) ? "exported " : null,
T_alias);
if (!iam_whence && !vflag)
shprintf("alias %s=", id);
shprintf("%s %s=", T_alias, id);
print_value_quoted(tp->val.s);
break;
case CFUNC:
if (vflag) {
shf_puts(" is a", shl_stdout);
if (tp->flag & EXPORT)
shf_puts("n exported", shl_stdout);
if (tp->flag & TRACE)
@ -827,8 +837,9 @@ c_whence(const char **wp)
break;
case CSHELL:
if (vflag)
shprintf(" is a%s shell builtin",
(tp->flag & SPEC_BI) ? " special" : null);
shprintf("%s %s %s",
(tp->flag & SPEC_BI) ? " special" : null,
"shell", T_builtin);
break;
case CTALIAS:
case CEXEC:
@ -836,14 +847,15 @@ c_whence(const char **wp)
if (vflag) {
shf_puts(" is ", shl_stdout);
if (tp->type == CTALIAS)
shprintf("a tracked %salias for ",
shprintf("a tracked %s%s for ",
(tp->flag & EXPORT) ?
"exported " : null);
"exported " : null,
T_alias);
}
shf_puts(tp->val.s, shl_stdout);
} else {
if (vflag)
shf_puts(" not found", shl_stdout);
shprintf(" %s\n", "not found");
rv = 1;
}
break;
@ -1051,7 +1063,7 @@ c_typeset(const char **wp)
"function %s %T\n" :
"%s() %T\n", wp[i], f->val.t);
} else if (!typeset(wp[i], fset, fclr, field, base)) {
bi_errorf("%s: not identifier", wp[i]);
bi_errorf("%s: %s", wp[i], "not identifier");
set_refflag = 0;
return (1);
}
@ -1120,27 +1132,27 @@ c_typeset(const char **wp)
*/
shf_puts("typeset ", shl_stdout);
if (((vp->flag&(ARRAY|ASSOC))==ASSOC))
shf_puts("-n ", shl_stdout);
shprintf("%s ", "-n");
if ((vp->flag&INTEGER))
shf_puts("-i ", shl_stdout);
shprintf("%s ", "-i");
if ((vp->flag&EXPORT))
shf_puts("-x ", shl_stdout);
shprintf("%s ", "-x");
if ((vp->flag&RDONLY))
shf_puts("-r ", shl_stdout);
shprintf("%s ", "-r");
if ((vp->flag&TRACE))
shf_puts("-t ", shl_stdout);
shprintf("%s ", "-t");
if ((vp->flag&LJUST))
shprintf("-L%d ", vp->u2.field);
if ((vp->flag&RJUST))
shprintf("-R%d ", vp->u2.field);
if ((vp->flag&ZEROFIL))
shf_puts("-Z ", shl_stdout);
shprintf("%s ", "-Z");
if ((vp->flag&LCASEV))
shf_puts("-l ", shl_stdout);
shprintf("%s ", "-l");
if ((vp->flag&UCASEV_AL))
shf_puts("-u ", shl_stdout);
shprintf("%s ", "-u");
if ((vp->flag&INT_U))
shf_puts("-U ", shl_stdout);
shprintf("%s ", "-U");
shf_puts(vp->name, shl_stdout);
if (pflag) {
char *s = str_val(vp);
@ -1259,12 +1271,12 @@ c_alias(const char **wp)
/* "hash -r" means reset all the tracked aliases.. */
if (rflag) {
static const char *args[] = {
"unalias", "-ta", NULL
T_unalias, "-ta", NULL
};
if (!tflag || *wp) {
shf_puts("alias: -r flag can only be used with -t"
" and without arguments\n", shl_stdout);
shprintf("%s: -r flag can only be used with -t"
" and without arguments\n", T_alias);
return (1);
}
ksh_getopt_reset(&builtin_opt, GF_ERROR);
@ -1277,7 +1289,7 @@ c_alias(const char **wp)
for (p = ktsort(t); (ap = *p++) != NULL; )
if ((ap->flag & (ISSET|xflag)) == (ISSET|xflag)) {
if (pflag)
shf_puts("alias ", shl_stdout);
shprintf("%s ", T_alias);
shf_puts(ap->name, shl_stdout);
if (prefix != '+') {
shf_putc('=', shl_stdout);
@ -1302,7 +1314,7 @@ c_alias(const char **wp)
ap = ktsearch(t, alias, h);
if (ap != NULL && (ap->flag&ISSET)) {
if (pflag)
shf_puts("alias ", shl_stdout);
shprintf("%s ", T_alias);
shf_puts(ap->name, shl_stdout);
if (prefix != '+') {
shf_putc('=', shl_stdout);
@ -1310,7 +1322,8 @@ c_alias(const char **wp)
}
shf_putc('\n', shl_stdout);
} else {
shprintf("%s alias not found\n", alias);
shprintf("%s %s %s\n", alias, T_alias,
"not found");
rv = 1;
}
continue;
@ -1583,8 +1596,8 @@ c_kill(const char **wp)
if (j_kill(p, sig))
rv = 1;
} else if (!getn(p, &n)) {
bi_errorf("%s: arguments must be jobs or process IDs",
p);
bi_errorf("%s: %s", p,
"arguments must be jobs or process IDs");
rv = 1;
} else {
if (mksh_kill(n, sig) < 0) {
@ -1619,22 +1632,22 @@ c_getopts(const char **wp)
opts = *wp++;
if (!opts) {
bi_errorf("missing options argument");
bi_errorf("missing %s argument", "options");
return (1);
}
var = *wp++;
if (!var) {
bi_errorf("missing name argument");
bi_errorf("missing %s argument", "name");
return (1);
}
if (!*var || *skip_varname(var, true)) {
bi_errorf("%s: is not an identifier", var);
bi_errorf("%s: %s", var, "is not an identifier");
return (1);
}
if (e->loc->next == NULL) {
internal_warningf("c_getopts: no argv");
internal_warningf("%s: %s", "c_getopts", "no argv");
return (1);
}
/* Which arguments are we parsing... */
@ -1777,7 +1790,7 @@ c_shift(const char **wp)
} else
n = 1;
if (n < 0) {
bi_errorf("%s: bad number", arg);
bi_errorf("%s: %s", arg, "bad number");
return (1);
}
if (l->argc < n) {
@ -1995,7 +2008,7 @@ c_read(const char **wp)
switch (optc) {
case 'p':
if ((fd = coproc_getfd(R_OK, &emsg)) < 0) {
bi_errorf("-p: %s", emsg);
bi_errorf("%s: %s", "-p", emsg);
return (1);
}
break;
@ -2009,7 +2022,7 @@ c_read(const char **wp)
if (!*(cp = builtin_opt.optarg))
fd = 0;
else if ((fd = check_fd(cp, R_OK, &emsg)) < 0) {
bi_errorf("-u: %s: %s", cp, emsg);
bi_errorf("%s: %s: %s", "-u", cp, emsg);
return (1);
}
break;
@ -2240,7 +2253,7 @@ c_trap(const char **wp)
while (*wp != NULL) {
p = gettrap(*wp++, true);
if (p == NULL) {
bi_errorf("bad signal %s", wp[-1]);
bi_errorf("bad signal '%s'", wp[-1]);
return (1);
}
settrap(p, s);
@ -2261,7 +2274,7 @@ c_exitreturn(const char **wp)
if (arg) {
if (!getn(arg, &n)) {
exstat = 1;
warningf(true, "%s: bad number", arg);
warningf(true, "%s: %s", arg, "bad number");
} else
exstat = n;
}
@ -2306,7 +2319,7 @@ c_brkcont(const char **wp)
quit = n;
if (quit <= 0) {
/* AT&T ksh does this for non-interactive shells only - weird */
bi_errorf("%s: bad value", arg);
bi_errorf("%s: %s", arg, "bad value");
return (1);
}
@ -2325,7 +2338,7 @@ c_brkcont(const char **wp)
* scripts, but don't generate an error (ie, keep going).
*/
if (n == quit) {
warningf(true, "%s: cannot %s", wp[0], wp[0]);
warningf(true, "%s: %s %s", wp[0], "cannot", wp[0]);
return (0);
}
/* POSIX says if n is too big, the last enclosing loop
@ -2351,7 +2364,7 @@ c_set(const char **wp)
const char **owp;
if (wp[1] == NULL) {
static const char *args[] = { "set", "-", NULL };
static const char *args[] = { T_set, "-", NULL };
return (c_typeset(args));
}
@ -2550,10 +2563,11 @@ timex_hook(struct op *t, char **volatile *app)
t->str[0] |= TF_POSIX;
break;
case '?':
errorf("time: -%s unknown option", opt.optarg);
errorf("time: -%s %s", opt.optarg,
"unknown option");
case ':':
errorf("time: -%s requires an argument",
opt.optarg);
errorf("time: -%s %s", opt.optarg,
"requires an argument");
}
/* Copy command words down over options. */
if (opt.optind != 0) {
@ -2641,21 +2655,21 @@ c_mknod(const char **wp)
majnum = strtoul(argv[2], &c, 0);
if ((c == argv[2]) || (*c != '\0')) {
bi_errorf("non-numeric device major '%s'", argv[2]);
bi_errorf("non-numeric %s %s '%s'", "device", "major", argv[2]);
goto c_mknod_err;
}
minnum = strtoul(argv[3], &c, 0);
if ((c == argv[3]) || (*c != '\0')) {
bi_errorf("non-numeric device minor '%s'", argv[3]);
bi_errorf("non-numeric %s %s '%s'", "device", "minor", argv[3]);
goto c_mknod_err;
}
dv = makedev(majnum, minnum);
if ((unsigned long)(major(dv)) != majnum) {
bi_errorf("device major too large: %lu", majnum);
bi_errorf("%s %s too large: %lu", "device", "major", majnum);
goto c_mknod_err;
}
if ((unsigned long)(minor(dv)) != minnum) {
bi_errorf("device minor too large: %lu", minnum);
bi_errorf("%s %s too large: %lu", "device", "minor", minnum);
goto c_mknod_err;
}
if (mknod(argv[0], mode, dv))
@ -2671,8 +2685,8 @@ c_mknod(const char **wp)
umask(oldmode);
return (rv);
c_mknod_usage:
bi_errorf("usage: mknod [-m mode] name b|c major minor");
bi_errorf("usage: mknod [-m mode] name p");
bi_errorf("%s: %s", "usage", "mknod [-m mode] name b|c major minor");
bi_errorf("%s: %s", "usage", "mknod [-m mode] name p");
return (1);
}
#endif
@ -3021,7 +3035,7 @@ test_primary(Test_env *te, bool do_eval)
if (te->flags & TEF_ERROR)
return (0);
if (!(*te->isa)(te, TM_CPAREN)) {
(*te->error)(te, 0, "missing closing paren");
(*te->error)(te, 0, "missing )");
return (0);
}
return (rv);
@ -3281,7 +3295,8 @@ c_ulimit(const char **wp)
all = true;
break;
case '?':
bi_errorf("usage: ulimit [-acdfHLlmnpSsTtvw] [value]");
bi_errorf("%s: %s", "usage",
"ulimit [-acdfHLlmnpSsTtvw] [value]");
return (1);
default:
what = optc;
@ -3388,7 +3403,7 @@ c_rename(const char **wp)
bi_errorf(T_synerr);
else if ((rv = rename(wp[1], wp[2])) != 0) {
rv = errno;
bi_errorf("failed: %s", strerror(rv));
bi_errorf("%s: %s", "failed", strerror(rv));
}
return (rv);