* shrink MKSH_SMALL even further by removing functionality like

some GNU bash extensions (suggested by cnuke@) and bind macros
* make the random cache more efficient (and the code potentially
  smaller, although we have a new implementation of the oaat hash
  function, alongside the old one, now) and pushb only if needed
  (i.e. state has changed or user has set $RANDOM, but not onfork)
This commit is contained in:
tg 2009-09-23 18:04:58 +00:00
parent 1ea1096a4e
commit 1a28786229
10 changed files with 194 additions and 62 deletions

14
check.t
View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.308 2009/09/20 17:23:49 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.309 2009/09/23 18:04:53 tg Exp $
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
@ -25,7 +25,7 @@
# http://www.research.att.com/~gsf/public/ifs.sh # http://www.research.att.com/~gsf/public/ifs.sh
expected-stdout: expected-stdout:
@(#)MIRBSD KSH R39 2009/09/20 @(#)MIRBSD KSH R39 2009/09/23
description: description:
Check version of shell. Check version of shell.
stdin: stdin:
@ -4969,6 +4969,7 @@ expected-stdout:
name: arrays-2 name: arrays-2
description: description:
Check if bash-style arrays work as expected Check if bash-style arrays work as expected
category: !smksh
stdin: stdin:
v="c d" v="c d"
foo=(a \$v "$v" '$v' b) foo=(a \$v "$v" '$v' b)
@ -4993,6 +4994,7 @@ expected-stdout:
name: arrays-4 name: arrays-4
description: description:
Check if Korn Shell arrays with specified indices work as expected Check if Korn Shell arrays with specified indices work as expected
category: !smksh
stdin: stdin:
v="c d" v="c d"
set -A foo -- [1]=\$v [2]="$v" [4]='$v' [0]=a [5]=b set -A foo -- [1]=\$v [2]="$v" [4]='$v' [0]=a [5]=b
@ -5003,6 +5005,7 @@ expected-stdout:
name: arrays-5 name: arrays-5
description: description:
Check if bash-style arrays with specified indices work as expected Check if bash-style arrays with specified indices work as expected
category: !smksh
stdin: stdin:
v="c d" v="c d"
foo=([1]=\$v [2]="$v" [4]='$v' [0]=a [5]=b) foo=([1]=\$v [2]="$v" [4]='$v' [0]=a [5]=b)
@ -5709,6 +5712,7 @@ expected-stdout:
name: integer-base-one-4 name: integer-base-one-4
description: description:
Check if ksh93-style base-one integers work Check if ksh93-style base-one integers work
category: !smksh
stdin: stdin:
set -U set -U
print 1 $(('a')) print 1 $(('a'))
@ -6151,6 +6155,7 @@ expected-stdout:
name: event-subst-1a name: event-subst-1a
description: description:
Check that '!' substitution in interactive mode works Check that '!' substitution in interactive mode works
category: !smksh
file-setup: file 755 "falsetto" file-setup: file 755 "falsetto"
#! /bin/sh #! /bin/sh
echo molto bene echo molto bene
@ -6178,6 +6183,7 @@ description:
even when a space separates it from the search command, even when a space separates it from the search command,
which is not what GNU bash provides but required for the which is not what GNU bash provides but required for the
other regression tests below to check other regression tests below to check
category: !smksh
file-setup: file 755 "falsetto" file-setup: file 755 "falsetto"
#! /bin/sh #! /bin/sh
echo molto bene echo molto bene
@ -6203,6 +6209,7 @@ name: event-subst-2
description: description:
Check that '!' substitution in interactive mode Check that '!' substitution in interactive mode
does not break things does not break things
category: !smksh
file-setup: file 755 "falsetto" file-setup: file 755 "falsetto"
#! /bin/sh #! /bin/sh
echo molto bene echo molto bene
@ -6238,6 +6245,7 @@ expected-stderr-pattern:
name: event-subst-3 name: event-subst-3
description: description:
Check that '!' substitution in noninteractive mode is ignored Check that '!' substitution in noninteractive mode is ignored
category: !smksh
file-setup: file 755 "falsetto" file-setup: file 755 "falsetto"
#! /bin/sh #! /bin/sh
echo molto bene echo molto bene
@ -6358,7 +6366,7 @@ stdin:
print ir2: $ir2 print ir2: $ir2
set|grep ^ir2|sed 's/^/s1: /' set|grep ^ir2|sed 's/^/s1: /'
typeset|grep ' ir2'|sed -e 's/^/s2: /' -e 's/nameref/typeset -n/' typeset|grep ' ir2'|sed -e 's/^/s2: /' -e 's/nameref/typeset -n/'
blub=(e1 e2 e3) set -A blub -- e1 e2 e3
typeset -n ind=blub typeset -n ind=blub
typeset -n ir2=blub[2] typeset -n ir2=blub[2]
print !ind[1]: ${!ind[1]} print !ind[1]: ${!ind[1]}

49
edit.c
View File

@ -25,7 +25,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.180 2009/09/20 17:23:50 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/edit.c,v 1.181 2009/09/23 18:04:54 tg Exp $");
/* tty driver characters we are interested in */ /* tty driver characters we are interested in */
typedef struct { typedef struct {
@ -1033,13 +1033,17 @@ static int x_nextcmd; /* for newline-and-next */
static char *xmp; /* mark pointer */ static char *xmp; /* mark pointer */
static unsigned char x_last_command; static unsigned char x_last_command;
static unsigned char (*x_tab)[X_TABSZ]; /* key definition */ static unsigned char (*x_tab)[X_TABSZ]; /* key definition */
#ifndef MKSH_SMALL
static char *(*x_atab)[X_TABSZ]; /* macro definitions */ static char *(*x_atab)[X_TABSZ]; /* macro definitions */
#endif
static unsigned char x_bound[(X_TABSZ * X_NTABS + 7) / 8]; static unsigned char x_bound[(X_TABSZ * X_NTABS + 7) / 8];
#define KILLSIZE 20 #define KILLSIZE 20
static char *killstack[KILLSIZE]; static char *killstack[KILLSIZE];
static int killsp, killtp; static int killsp, killtp;
static int x_curprefix; static int x_curprefix;
#ifndef MKSH_SMALL
static char *macroptr = NULL; /* bind key macro active? */ static char *macroptr = NULL; /* bind key macro active? */
#endif
#ifndef MKSH_NOVI #ifndef MKSH_NOVI
static int cur_col; /* current column on line */ static int cur_col; /* current column on line */
static int pwidth; /* width of prompt */ static int pwidth; /* width of prompt */
@ -1069,6 +1073,9 @@ static void x_load_hist(char **);
static int x_search(char *, int, int); static int x_search(char *, int, int);
#ifndef MKSH_SMALL #ifndef MKSH_SMALL
static int x_search_dir(int); static int x_search_dir(int);
int x_bind(const char *, const char *, bool, bool);
#else
int x_bind(const char *, const char *, bool);
#endif #endif
static int x_match(char *, char *); static int x_match(char *, char *);
static void x_redraw(int); static void x_redraw(int);
@ -1314,11 +1321,11 @@ x_emacs(char *buf, size_t len)
if ((i = x_e_getc()) != '~') if ((i = x_e_getc()) != '~')
x_e_ungetc(i); x_e_ungetc(i);
} }
#endif
/* avoid bind key macro recursion */ /* avoid bind key macro recursion */
if (macroptr && f == XFUNC_ins_string) if (macroptr && f == XFUNC_ins_string)
f = XFUNC_insert; f = XFUNC_insert;
#endif
if (!(x_ftab[f].xf_flags & XF_PREFIX) && if (!(x_ftab[f].xf_flags & XF_PREFIX) &&
x_last_command != XFUNC_set_arg) { x_last_command != XFUNC_set_arg) {
@ -1402,6 +1409,7 @@ x_insert(int c)
return (KSTD); return (KSTD);
} }
#ifndef MKSH_SMALL
static int static int
x_ins_string(int c) x_ins_string(int c)
{ {
@ -1412,6 +1420,7 @@ x_ins_string(int c)
*/ */
return (KSTD); return (KSTD);
} }
#endif
static int static int
x_do_ins(const char *cp, size_t len) x_do_ins(const char *cp, size_t len)
@ -2503,22 +2512,27 @@ x_print(int prefix, int key)
shprintf("%s = ", x_mapout(key)); shprintf("%s = ", x_mapout(key));
#else #else
shprintf("%s%s = ", x_mapout(key), (f & 0x80) ? "~" : ""); shprintf("%s%s = ", x_mapout(key), (f & 0x80) ? "~" : "");
#endif
if (XFUNC_VALUE(f) != XFUNC_ins_string) if (XFUNC_VALUE(f) != XFUNC_ins_string)
#endif
shprintf("%s\n", x_ftab[XFUNC_VALUE(f)].xf_name); shprintf("%s\n", x_ftab[XFUNC_VALUE(f)].xf_name);
#ifndef MKSH_SMALL
else else
shprintf("'%s'\n", x_atab[prefix][key]); shprintf("'%s'\n", x_atab[prefix][key]);
#endif
} }
int int
x_bind(const char *a1, const char *a2, x_bind(const char *a1, const char *a2,
#ifndef MKSH_SMALL
bool macro, /* bind -m */ bool macro, /* bind -m */
#endif
bool list) /* bind -l */ bool list) /* bind -l */
{ {
unsigned char f; unsigned char f;
int prefix, key; int prefix, key;
char *sp = NULL, *m1, *m2; char *m1, *m2;
#ifndef MKSH_SMALL #ifndef MKSH_SMALL
char *sp = NULL;
bool hastilde; bool hastilde;
#endif #endif
@ -2538,8 +2552,11 @@ x_bind(const char *a1, const char *a2,
for (prefix = 0; prefix < X_NTABS; prefix++) for (prefix = 0; prefix < X_NTABS; prefix++)
for (key = 0; key < X_TABSZ; key++) { for (key = 0; key < X_TABSZ; key++) {
f = XFUNC_VALUE(x_tab[prefix][key]); f = XFUNC_VALUE(x_tab[prefix][key]);
if (f == XFUNC_insert || f == XFUNC_error || if (f == XFUNC_insert || f == XFUNC_error
(macro && f != XFUNC_ins_string)) #ifndef MKSH_SMALL
|| (macro && f != XFUNC_ins_string)
#endif
)
continue; continue;
x_print(prefix, key); x_print(prefix, key);
} }
@ -2579,9 +2596,14 @@ x_bind(const char *a1, const char *a2,
x_print(prefix, key); x_print(prefix, key);
return (0); return (0);
} }
if (*a2 == 0) if (*a2 == 0) {
f = XFUNC_insert; f = XFUNC_insert;
else if (!macro) { #ifndef MKSH_SMALL
} else if (macro) {
f = XFUNC_ins_string;
sp = x_mapin(a2, AEDIT);
#endif
} else {
for (f = 0; f < NELEM(x_ftab); f++) for (f = 0; f < NELEM(x_ftab); f++)
if (x_ftab[f].xf_name && if (x_ftab[f].xf_name &&
strcmp(x_ftab[f].xf_name, a2) == 0) strcmp(x_ftab[f].xf_name, a2) == 0)
@ -2590,20 +2612,21 @@ x_bind(const char *a1, const char *a2,
bi_errorf("%s: no such function", a2); bi_errorf("%s: no such function", a2);
return (1); return (1);
} }
} else {
f = XFUNC_ins_string;
sp = x_mapin(a2, AEDIT);
} }
#ifndef MKSH_SMALL
if (XFUNC_VALUE(x_tab[prefix][key]) == XFUNC_ins_string && if (XFUNC_VALUE(x_tab[prefix][key]) == XFUNC_ins_string &&
x_atab[prefix][key]) x_atab[prefix][key])
afree(x_atab[prefix][key], AEDIT); afree(x_atab[prefix][key], AEDIT);
#endif
x_tab[prefix][key] = f x_tab[prefix][key] = f
#ifndef MKSH_SMALL #ifndef MKSH_SMALL
| (hastilde ? 0x80 : 0) | (hastilde ? 0x80 : 0)
#endif #endif
; ;
#ifndef MKSH_SMALL
x_atab[prefix][key] = sp; x_atab[prefix][key] = sp;
#endif
/* Track what the user has bound so x_mode(true) won't toast things */ /* Track what the user has bound so x_mode(true) won't toast things */
if (f == XFUNC_insert) if (f == XFUNC_insert)
@ -2634,10 +2657,12 @@ x_init_emacs(void)
x_tab[x_defbindings[i].xdb_tab][x_defbindings[i].xdb_char] x_tab[x_defbindings[i].xdb_tab][x_defbindings[i].xdb_char]
= x_defbindings[i].xdb_func; = x_defbindings[i].xdb_func;
#ifndef MKSH_SMALL
x_atab = alloc(X_NTABS * sizeof(*x_atab), AEDIT); x_atab = alloc(X_NTABS * sizeof(*x_atab), AEDIT);
for (i = 1; i < X_NTABS; i++) for (i = 1; i < X_NTABS; i++)
for (j = 0; j < X_TABSZ; j++) for (j = 0; j < X_TABSZ; j++)
x_atab[i][j] = NULL; x_atab[i][j] = NULL;
#endif
} }
static void static void
@ -2876,11 +2901,13 @@ x_e_getc(void)
return (c); return (c);
} }
#ifndef MKSH_SMALL
if (macroptr) { if (macroptr) {
if ((c = (unsigned char)*macroptr++)) if ((c = (unsigned char)*macroptr++))
return (c); return (c);
macroptr = NULL; macroptr = NULL;
} }
#endif
return (x_getc()); return (x_getc());
} }

View File

@ -1,5 +1,5 @@
#if defined(EMACSFN_DEFNS) #if defined(EMACSFN_DEFNS)
__RCSID("$MirOS: src/bin/mksh/emacsfn.h,v 1.3 2009/09/20 17:23:51 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/emacsfn.h,v 1.4 2009/09/23 18:04:55 tg Exp $");
#define FN(cname,sname,flags) static int x_##cname(int); #define FN(cname,sname,flags) static int x_##cname(int);
#elif defined(EMACSFN_ENUMS) #elif defined(EMACSFN_ENUMS)
#define FN(cname,sname,flags) XFUNC_##cname, #define FN(cname,sname,flags) XFUNC_##cname,
@ -41,7 +41,9 @@ FN(fold_lower, downcase-word, XF_ARG)
FN(fold_upper, upcase-word, XF_ARG) FN(fold_upper, upcase-word, XF_ARG)
#endif #endif
FN(goto_hist, goto-history, XF_ARG) FN(goto_hist, goto-history, XF_ARG)
#ifndef MKSH_SMALL
FN(ins_string, macro-string, XF_NOBIND) FN(ins_string, macro-string, XF_NOBIND)
#endif
FN(insert, auto-insert, XF_ARG) FN(insert, auto-insert, XF_ARG)
FN(kill, kill-to-eol, XF_ARG) FN(kill, kill-to-eol, XF_ARG)
FN(kill_region, kill-region, 0) FN(kill_region, kill-region, 0)

4
expr.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.34 2009/09/06 17:55:54 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/expr.c,v 1.35 2009/09/23 18:04:55 tg Exp $");
/* The order of these enums is constrained by the order of opinfo[] */ /* The order of these enums is constrained by the order of opinfo[] */
enum token { enum token {
@ -528,6 +528,7 @@ exprtoken(Expr_state *es)
cp += utf_ptradj(cp); cp += utf_ptradj(cp);
strndupx(tvar, es->tokp, cp - es->tokp, ATEMP); strndupx(tvar, es->tokp, cp - es->tokp, ATEMP);
goto process_tvar; goto process_tvar;
#ifndef MKSH_SMALL
} else if (c == '\'') { } else if (c == '\'') {
++cp; ++cp;
cp += utf_ptradj(cp); cp += utf_ptradj(cp);
@ -542,6 +543,7 @@ exprtoken(Expr_state *es)
memcpy(tvar + 2, es->tokp + 1, c - 2); memcpy(tvar + 2, es->tokp + 1, c - 2);
tvar[c] = '\0'; tvar[c] = '\0';
goto process_tvar; goto process_tvar;
#endif
} else if (ksh_isdigit(c)) { } else if (ksh_isdigit(c)) {
while (c != '_' && (ksh_isalnux(c) || c == '#')) while (c != '_' && (ksh_isalnux(c) || c == '#'))
c = *cp++; c = *cp++;

35
funcs.c
View File

@ -25,7 +25,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.133 2009/09/19 21:54:44 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.134 2009/09/23 18:04:56 tg Exp $");
#if HAVE_KILLPG #if HAVE_KILLPG
/* /*
@ -1652,29 +1652,50 @@ c_getopts(const char **wp)
return (optc < 0 ? 1 : rv); return (optc < 0 ? 1 : rv);
} }
#ifndef MKSH_SMALL
extern int x_bind(const char *, const char *, bool, bool);
#else
extern int x_bind(const char *, const char *, bool);
#endif
int int
c_bind(const char **wp) c_bind(const char **wp)
{ {
int optc, rv = 0; int optc, rv = 0;
bool macro = false, list = false; #ifndef MKSH_SMALL
bool macro = false;
#endif
bool list = false;
const char *cp; const char *cp;
char *up; char *up;
while ((optc = ksh_getopt(wp, &builtin_opt, "lm")) != -1) while ((optc = ksh_getopt(wp, &builtin_opt,
#ifndef MKSH_SMALL
"lm"
#else
"l"
#endif
)) != -1)
switch (optc) { switch (optc) {
case 'l': case 'l':
list = true; list = true;
break; break;
#ifndef MKSH_SMALL
case 'm': case 'm':
macro = true; macro = true;
break; break;
#endif
case '?': case '?':
return (1); return (1);
} }
wp += builtin_opt.optind; wp += builtin_opt.optind;
if (*wp == NULL) /* list all */ if (*wp == NULL) /* list all */
rv = x_bind(NULL, NULL, 0, list); rv = x_bind(NULL, NULL,
#ifndef MKSH_SMALL
false,
#endif
list);
for (; *wp != NULL; wp++) { for (; *wp != NULL; wp++) {
if ((cp = cstrchr(*wp, '=')) == NULL) if ((cp = cstrchr(*wp, '=')) == NULL)
@ -1683,7 +1704,11 @@ c_bind(const char **wp)
strdupx(up, *wp, ATEMP); strdupx(up, *wp, ATEMP);
up[cp++ - *wp] = '\0'; up[cp++ - *wp] = '\0';
} }
if (x_bind(up ? up : *wp, cp, macro, 0)) if (x_bind(up ? up : *wp, cp,
#ifndef MKSH_SMALL
macro,
#endif
false))
rv = 1; rv = 1;
afree(up, ATEMP); afree(up, ATEMP);
} }

45
lex.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.95 2009/09/19 22:33:10 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/lex.c,v 1.96 2009/09/23 18:04:56 tg Exp $");
/* /*
* states while lexing word * states while lexing word
@ -77,11 +77,13 @@ struct lex_state {
#define ls_sbquote ls_info.u_sbquote #define ls_sbquote ls_info.u_sbquote
} u_sbquote; } u_sbquote;
#ifndef MKSH_SMALL
/* =(...) */ /* =(...) */
struct sletarray_info { struct sletarray_info {
int nparen; /* count open parentheses */ int nparen; /* count open parentheses */
#define ls_sletarray ls_info.u_sletarray #define ls_sletarray ls_info.u_sletarray
} u_sletarray; } u_sletarray;
#endif
/* ADELIM */ /* ADELIM */
struct sadelim_info { struct sadelim_info {
@ -129,13 +131,34 @@ static int backslash_skip;
static int ignore_backslash_newline; static int ignore_backslash_newline;
/* optimised getsc_bn() */ /* optimised getsc_bn() */
#define getsc() (*source->str != '\0' && *source->str != '\\' \ #define _getsc() (*source->str != '\0' && *source->str != '\\' \
&& !backslash_skip && !(source->flags & SF_FIRST) \ && !backslash_skip && !(source->flags & SF_FIRST) \
? *source->str++ : getsc_bn()) ? *source->str++ : getsc_bn())
/* optimised getsc__() */ /* optimised getsc__() */
#define getsc_() ((*source->str != '\0') && !(source->flags & SF_FIRST) \ #define _getsc_() ((*source->str != '\0') && !(source->flags & SF_FIRST) \
? *source->str++ : getsc__()) ? *source->str++ : getsc__())
#ifdef MKSH_SMALL
static int getsc(void);
static int getsc_(void);
static int
getsc(void)
{
return (_getsc());
}
static int
getsc_(void)
{
return (_getsc_());
}
#else
/* !MKSH_SMALL: use them inline */
#define getsc() _getsc()
#define getsc_() _getsc_()
#endif
#define STATE_BSIZE 32 #define STATE_BSIZE 32
#define PUSH_STATE(s) do { \ #define PUSH_STATE(s) do { \
@ -186,9 +209,11 @@ yylex(int cf)
*wp++ = OQUOTE; /* enclose arguments in (double) quotes */ *wp++ = OQUOTE; /* enclose arguments in (double) quotes */
state = SLETPAREN; state = SLETPAREN;
statep->ls_sletparen.nparen = 0; statep->ls_sletparen.nparen = 0;
#ifndef MKSH_SMALL
} else if (cf&LETARRAY) { } else if (cf&LETARRAY) {
state = SLETARRAY; state = SLETARRAY;
statep->ls_sletarray.nparen = 0; statep->ls_sletarray.nparen = 0;
#endif
} else { /* normal lexing */ } else { /* normal lexing */
state = (cf & HEREDELIM) ? SHEREDELIM : SBASE; state = (cf & HEREDELIM) ? SHEREDELIM : SBASE;
while ((c = getsc()) == ' ' || c == '\t') while ((c = getsc()) == ' ' || c == '\t')
@ -711,6 +736,7 @@ yylex(int cf)
++statep->ls_sletparen.nparen; ++statep->ls_sletparen.nparen;
goto Sbase2; goto Sbase2;
#ifndef MKSH_SMALL
case SLETARRAY: /* LETARRAY: =( ... ) */ case SLETARRAY: /* LETARRAY: =( ... ) */
if (c == '('/*)*/) if (c == '('/*)*/)
++statep->ls_sletarray.nparen; ++statep->ls_sletarray.nparen;
@ -721,6 +747,7 @@ yylex(int cf)
} }
*wp++ = CHAR, *wp++ = c; *wp++ = CHAR, *wp++ = c;
break; break;
#endif
case SHERESTRING: /* <<< delimiter */ case SHERESTRING: /* <<< delimiter */
if (c == '\\') { if (c == '\\') {
@ -842,8 +869,10 @@ yylex(int cf)
/* XXX figure out what is missing */ /* XXX figure out what is missing */
yyerror("no closing quote\n"); yyerror("no closing quote\n");
#ifndef MKSH_SMALL
if (state == SLETARRAY && statep->ls_sletarray.nparen != -1) if (state == SLETARRAY && statep->ls_sletarray.nparen != -1)
yyerror("%s: ')' missing\n", T_synerr); yyerror("%s: ')' missing\n", T_synerr);
#endif
/* This done to avoid tests for SHEREDELIM wherever SBASE tested */ /* This done to avoid tests for SHEREDELIM wherever SBASE tested */
if (state == SHEREDELIM || state == SHERESTRING) if (state == SHEREDELIM || state == SHERESTRING)
@ -937,8 +966,12 @@ yylex(int cf)
*wp++ = EOS; /* terminate word */ *wp++ = EOS; /* terminate word */
yylval.cp = Xclose(ws, wp); yylval.cp = Xclose(ws, wp);
if (state == SWORD || state == SLETPAREN || if (state == SWORD || state == SLETPAREN
state == SLETARRAY) /* ONEWORD? */ /* XXX ONEWORD? */
#ifndef MKSH_SMALL
|| state == SLETARRAY
#endif
)
return (LWORD); return (LWORD);
/* unget terminator */ /* unget terminator */
@ -1344,6 +1377,7 @@ getsc_line(Source *s)
alarm(0); alarm(0);
} }
cp = Xstring(s->xs, xp); cp = Xstring(s->xs, xp);
#ifndef MKSH_SMALL
if (interactive && *cp == '!' && cur_prompt == PS1) { if (interactive && *cp == '!' && cur_prompt == PS1) {
int linelen; int linelen;
@ -1361,6 +1395,7 @@ getsc_line(Source *s)
/* prepend it with "fc -e -" */ /* prepend it with "fc -e -" */
memcpy(cp, fc_e_, fc_e_n); memcpy(cp, fc_e_, fc_e_n);
} }
#endif
s->start = s->str = cp; s->start = s->str = cp;
strip_nuls(Xstring(s->xs, xp), Xlength(s->xs, xp)); strip_nuls(Xstring(s->xs, xp), Xlength(s->xs, xp));
/* Note: if input is all nulls, this is not eof */ /* Note: if input is all nulls, this is not eof */

23
main.c
View File

@ -33,7 +33,7 @@
#include <locale.h> #include <locale.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.145 2009/09/20 16:40:55 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/main.c,v 1.146 2009/09/23 18:04:57 tg Exp $");
extern char **environ; extern char **environ;
@ -1263,6 +1263,27 @@ hash(const char *cp)
return (h); return (h);
} }
#if !HAVE_ARC4RANDOM || !defined(MKSH_SMALL)
uint32_t
hashmem(const void *cp, size_t len)
{
register uint32_t h = 0;
register const uint8_t *bp = (const uint8_t *)cp;
while (len--) {
h += *bp++;
h += h << 10;
h ^= h >> 6;
}
h += h << 3;
h ^= h >> 11;
h += h << 15;
return (h);
}
#endif
static void static void
texpand(struct table *tp, size_t nsize) texpand(struct table *tp, size_t nsize)
{ {

6
sh.h
View File

@ -134,9 +134,9 @@
#endif #endif
#ifdef EXTERN #ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.346 2009/09/20 17:23:52 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.347 2009/09/23 18:04:57 tg Exp $");
#endif #endif
#define MKSH_VERSION "R39 2009/09/20" #define MKSH_VERSION "R39 2009/09/23"
#ifndef MKSH_INCLUDES_ONLY #ifndef MKSH_INCLUDES_ONLY
@ -1329,7 +1329,6 @@ void afree(void *, Area *); /* can take NULL */
/* edit.c */ /* edit.c */
void x_init(void); void x_init(void);
int x_read(char *, size_t); int x_read(char *, size_t);
int x_bind(const char *, const char *, bool, bool);
/* UTF-8 stuff */ /* UTF-8 stuff */
size_t utf_mbtowc(unsigned int *, const char *); size_t utf_mbtowc(unsigned int *, const char *);
size_t utf_wctomb(char *, unsigned int); size_t utf_wctomb(char *, unsigned int);
@ -1514,6 +1513,7 @@ int coproc_getfd(int, const char **);
void coproc_cleanup(int); void coproc_cleanup(int);
struct temp *maketemp(Area *, Temp_type, struct temp **); struct temp *maketemp(Area *, Temp_type, struct temp **);
uint32_t hash(const char *); uint32_t hash(const char *);
uint32_t hashmem(const void *, size_t);
void ktinit(struct table *, Area *, size_t); void ktinit(struct table *, Area *, size_t);
struct tbl *ktsearch(struct table *, const char *, uint32_t); struct tbl *ktsearch(struct table *, const char *, uint32_t);
struct tbl *ktenter(struct table *, const char *, uint32_t); struct tbl *ktenter(struct table *, const char *, uint32_t);

6
syn.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.42 2009/09/19 18:36:59 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/syn.c,v 1.43 2009/09/23 18:04:58 tg Exp $");
struct nesting_state { struct nesting_state {
int start_token; /* token than began nesting (eg, FOR) */ int start_token; /* token than began nesting (eg, FOR) */
@ -289,9 +289,11 @@ get_command(int cf)
ACCEPT; ACCEPT;
goto Subshell; goto Subshell;
} }
#ifndef MKSH_SMALL
if ((XPsize(args) == 0 || Flag(FKEYWORD)) && if ((XPsize(args) == 0 || Flag(FKEYWORD)) &&
XPsize(vars) == 1 && is_wdvarassign(yylval.cp)) XPsize(vars) == 1 && is_wdvarassign(yylval.cp))
goto is_wdarrassign; goto is_wdarrassign;
#endif
/* Must be a function */ /* Must be a function */
if (iopn != 0 || XPsize(args) != 1 || if (iopn != 0 || XPsize(args) != 1 ||
XPsize(vars) != 0) XPsize(vars) != 0)
@ -301,6 +303,7 @@ get_command(int cf)
musthave(')', 0); musthave(')', 0);
t = function_body(XPptrv(args)[0], false); t = function_body(XPptrv(args)[0], false);
goto Leave; goto Leave;
#ifndef MKSH_SMALL
is_wdarrassign: is_wdarrassign:
{ {
static const char set_cmd0[] = { static const char set_cmd0[] = {
@ -336,6 +339,7 @@ get_command(int cf)
XPput(args, yylval.cp); XPput(args, yylval.cp);
break; break;
} }
#endif
default: default:
goto Leave; goto Leave;

70
var.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.89 2009/09/20 13:29:18 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/var.c,v 1.90 2009/09/23 18:04:58 tg Exp $");
/* /*
* Variables * Variables
@ -973,13 +973,18 @@ makenv(void)
#if HAVE_ARC4RANDOM && !defined(MKSH_SMALL) #if HAVE_ARC4RANDOM && !defined(MKSH_SMALL)
static uint32_t rnd_cache[2]; static uint32_t rnd_cache[2];
static unsigned char rnd_lastflag = 2; static unsigned char rnd_lastflag = 2;
#if HAVE_ARC4RANDOM_PUSHB
static bool rnd_wpush = false;
#define rnd_mix(v,w) rnd_cmix(v,w)
#else
#define rnd_mix(v,w) rnd_cmix(v)
#endif
static void rnd_cachemix(unsigned long); static void rnd_mix(unsigned long, bool);
static void static void
rnd_cachemix(unsigned long newval) rnd_mix(unsigned long newval, bool wantpush)
{ {
size_t i;
struct { struct {
union { union {
int rval; int rval;
@ -988,31 +993,26 @@ rnd_cachemix(unsigned long newval)
uint32_t v1; uint32_t v1;
uint32_t v2; uint32_t v2;
unsigned long v3; unsigned long v3;
#if HAVE_ARC4RANDOM_PUSHB
bool neededpush;
bool wantingpush;
#endif
} v; } v;
unsigned char buf[sizeof(v) * 2 + 1], *cp, num;
#if HAVE_ARC4RANDOM_PUSHB
v.neededpush = rnd_wpush;
v.wantingpush = wantpush;
rnd_wpush = v.neededpush || v.wantingpush;
#endif
v.v0.rval = rand(); v.v0.rval = rand();
v.v1 = rnd_cache[0]; v.v1 = rnd_cache[0];
v.v2 = rnd_cache[1]; v.v2 = rnd_cache[1];
v.v3 = newval; v.v3 = newval;
num = 0; rnd_cache[0] = hashmem(&v, sizeof(v));
loop: v.v0.arval = arc4random();
cp = (void *)&v; rnd_cache[1] = hashmem(&v, sizeof(v));
i = 0;
while (i < 2 * sizeof(v)) {
buf[i++] = digits_uc[*cp >> 4];
buf[i++] = digits_lc[*cp & 0x0F];
++cp;
}
buf[i] = 0;
rnd_cache[num] = hash(buf);
if (num == 0) {
++num;
v.v0.arval = arc4random();
goto loop;
}
} }
#endif #endif
@ -1032,17 +1032,21 @@ rnd_get(void)
srand(arc4random() & 0x7FFF); srand(arc4random() & 0x7FFF);
else if (rnd_lastflag == 0) else if (rnd_lastflag == 0)
/* transition from 0: addrandom */ /* transition from 0: addrandom */
rnd_cachemix(rand()); rnd_mix(rand(), true);
rnd_lastflag = Flag(FARC4RANDOM); rnd_lastflag = Flag(FARC4RANDOM);
} }
if (Flag(FARC4RANDOM)) { if (Flag(FARC4RANDOM)) {
if (rnd_cache[0] || rnd_cache[1]) if (rnd_cache[0] || rnd_cache[1]) {
#if HAVE_ARC4RANDOM_PUSHB #if HAVE_ARC4RANDOM_PUSHB
rv = arc4random_pushb(rnd_cache, sizeof(rnd_cache)); if (rnd_wpush) {
#else rv = arc4random_pushb(rnd_cache,
sizeof(rnd_cache));
rnd_wpush = false;
} else
#endif
arc4random_addrandom((void *)rnd_cache, arc4random_addrandom((void *)rnd_cache,
sizeof(rnd_cache)); sizeof(rnd_cache));
#endif }
rnd_cache[0] = rnd_cache[1] = 0; rnd_cache[0] = rnd_cache[1] = 0;
return (( return ((
#if HAVE_ARC4RANDOM_PUSHB #if HAVE_ARC4RANDOM_PUSHB
@ -1066,7 +1070,7 @@ rnd_set(unsigned long newval)
#endif #endif
#else #else
#if HAVE_ARC4RANDOM #if HAVE_ARC4RANDOM
rnd_cachemix(newval); rnd_mix(newval, true);
if (Flag(FARC4RANDOM) == 1) if (Flag(FARC4RANDOM) == 1)
return; return;
if (Flag(FARC4RANDOM) == 2) if (Flag(FARC4RANDOM) == 2)
@ -1080,9 +1084,9 @@ rnd_set(unsigned long newval)
#if !HAVE_ARC4RANDOM || !defined(MKSH_SMALL) #if !HAVE_ARC4RANDOM || !defined(MKSH_SMALL)
/* /*
* Called after a fork in parent to bump the random number generator. * Called after a fork to bump the random number generator.
* Done to ensure children will not get the same random number sequence * Done to ensure children will not get the same random number sequence
* if the parent doesn't use $RANDOM. * as the parent processes.
*/ */
void void
change_random(unsigned long newval) change_random(unsigned long newval)
@ -1091,7 +1095,7 @@ change_random(unsigned long newval)
#if HAVE_ARC4RANDOM #if HAVE_ARC4RANDOM
if (Flag(FARC4RANDOM)) { if (Flag(FARC4RANDOM)) {
rnd_cachemix(newval); rnd_mix(newval, false);
return; return;
} }
#endif #endif
@ -1413,7 +1417,9 @@ set_array(const char *var, bool reset, const char **vals)
struct tbl *vp, *vq; struct tbl *vp, *vq;
mksh_uari_t i, n; mksh_uari_t i, n;
const char *ccp; const char *ccp;
#ifndef MKSH_SMALL
char *cp; char *cp;
#endif
/* to get local array, use "typeset foo; set -A foo" */ /* to get local array, use "typeset foo; set -A foo" */
vp = global(var); vp = global(var);
@ -1430,6 +1436,7 @@ set_array(const char *var, bool reset, const char **vals)
* evaluation of some of vals[] may fail... * evaluation of some of vals[] may fail...
*/ */
for (n = i = 0; (ccp = vals[i]); n = ++i) { for (n = i = 0; (ccp = vals[i]); n = ++i) {
#ifndef MKSH_SMALL
if (*ccp == '[') { if (*ccp == '[') {
int level = 0; int level = 0;
@ -1449,6 +1456,7 @@ set_array(const char *var, bool reset, const char **vals)
} else } else
ccp = vals[i]; ccp = vals[i];
} }
#endif
vq = arraysearch(vp, n); vq = arraysearch(vp, n);
/* would be nice to deal with errors here... (see above) */ /* would be nice to deal with errors here... (see above) */