• merge printf from OpenBSD

• deactivate %a and %A since our libc doesn’t have it
• rewrite the mksh integration code to use shf instead of stdio, removing
  floating point support always in the process, as shf doesn’t support it
  ⇒ saves 11114 (6706 text, 168 data, 4240 bss) with dietlibc on Debian
• fix -Wall -Wextra -Wformat -Wstrict-aliasing=2 for gcc (Debian 4.4.4-7)
• fix these and -Wc++-compat for gcc version 4.6.0 20100711 (experimental)
  [trunk revision 162057] (Debian 20100711-1) except:
  – a few enum warnings that relate to eglibc’s {g,s}etrlimit() functions
    taking an enum instead of an int because they’re too stupid to adhere
    to POSIX interfaces they design by themselves
  – all “request for implicit conversion” involving a "void *" on one side
• tweak the manual page somewhat more
This commit is contained in:
tg
2010-07-17 22:09:40 +00:00
parent 1e113b416b
commit 7c91e018f4
13 changed files with 189 additions and 182 deletions

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.381 2010/07/13 13:12:28 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.382 2010/07/17 22:09:30 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 2010/07/13 @(#)MIRBSD KSH R39 2010/07/17
description: description:
Check version of shell. Check version of shell.
stdin: stdin:

40
edit.c
View File

@ -25,7 +25,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.194 2010/07/04 18:52:52 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/edit.c,v 1.195 2010/07/17 22:09:32 tg Exp $");
/* /*
* in later versions we might use libtermcap for this, but since external * in later versions we might use libtermcap for this, but since external
@ -2258,13 +2258,13 @@ x_vt_hack(int c)
static char * static char *
x_mapin(const char *cp, Area *ap) x_mapin(const char *cp, Area *ap)
{ {
char *new, *op; char *news, *op;
/* for clang's static analyser, the nonnull attribute isn't enough */ /* for clang's static analyser, the nonnull attribute isn't enough */
mkssert(cp != NULL); mkssert(cp != NULL);
strdupx(new, cp, ap); strdupx(news, cp, ap);
op = new; op = news;
while (*cp) { while (*cp) {
/* XXX -- should handle \^ escape? */ /* XXX -- should handle \^ escape? */
if (*cp == '^') { if (*cp == '^') {
@ -2281,7 +2281,7 @@ x_mapin(const char *cp, Area *ap)
} }
*op = '\0'; *op = '\0';
return (new); return (news);
} }
static void static void
@ -3311,7 +3311,7 @@ static const unsigned char classify[128] = {
static char undocbuf[LINE]; static char undocbuf[LINE];
static struct edstate *save_edstate(struct edstate *old); static struct edstate *save_edstate(struct edstate *old);
static void restore_edstate(struct edstate *old, struct edstate *new); static void restore_edstate(struct edstate *old, struct edstate *news);
static void free_edstate(struct edstate *old); static void free_edstate(struct edstate *old);
static struct edstate ebuf; static struct edstate ebuf;
@ -4573,25 +4573,25 @@ restore_cbuf(void)
static struct edstate * static struct edstate *
save_edstate(struct edstate *old) save_edstate(struct edstate *old)
{ {
struct edstate *new; struct edstate *news;
new = alloc(sizeof(struct edstate), APERM); news = alloc(sizeof(struct edstate), APERM);
new->cbuf = alloc(old->cbufsize, APERM); news->cbuf = alloc(old->cbufsize, APERM);
memcpy(new->cbuf, old->cbuf, old->linelen); memcpy(news->cbuf, old->cbuf, old->linelen);
new->cbufsize = old->cbufsize; news->cbufsize = old->cbufsize;
new->linelen = old->linelen; news->linelen = old->linelen;
new->cursor = old->cursor; news->cursor = old->cursor;
new->winleft = old->winleft; news->winleft = old->winleft;
return (new); return (news);
} }
static void static void
restore_edstate(struct edstate *new, struct edstate *old) restore_edstate(struct edstate *news, struct edstate *old)
{ {
memcpy(new->cbuf, old->cbuf, old->linelen); memcpy(news->cbuf, old->cbuf, old->linelen);
new->linelen = old->linelen; news->linelen = old->linelen;
new->cursor = old->cursor; news->cursor = old->cursor;
new->winleft = old->winleft; news->winleft = old->winleft;
free_edstate(old); free_edstate(old);
} }

122
emacsfn.h
View File

@ -1,86 +1,86 @@
#if defined(EMACSFN_DEFNS) #if defined(EMACSFN_DEFNS)
__RCSID("$MirOS: src/bin/mksh/emacsfn.h,v 1.4 2009/09/23 18:04:55 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/emacsfn.h,v 1.5 2010/07/17 22:09:33 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,
#define F0(cname,sname,flags) XFUNC_##cname = 0, #define F0(cname,sname,flags) XFUNC_##cname = 0,
#elif defined(EMACSFN_ITEMS) #elif defined(EMACSFN_ITEMS)
#define FN(cname,sname,flags) { x_##cname, #sname, flags }, #define FN(cname,sname,flags) { x_##cname, sname, flags },
#endif #endif
#ifndef F0 #ifndef F0
#define F0 FN #define F0 FN
#endif #endif
F0(abort, abort, 0) F0(abort, "abort", 0)
FN(beg_hist, beginning-of-history, 0) FN(beg_hist, "beginning-of-history", 0)
FN(cls, clear-screen, 0) FN(cls, "clear-screen", 0)
FN(comment, comment, 0) FN(comment, "comment", 0)
FN(comp_comm, complete-command, 0) FN(comp_comm, "complete-command", 0)
FN(comp_file, complete-file, 0) FN(comp_file, "complete-file", 0)
FN(comp_list, complete-list, 0) FN(comp_list, "complete-list", 0)
FN(complete, complete, 0) FN(complete, "complete", 0)
FN(del_back, delete-char-backward, XF_ARG) FN(del_back, "delete-char-backward", XF_ARG)
FN(del_bword, delete-word-backward, XF_ARG) FN(del_bword, "delete-word-backward", XF_ARG)
FN(del_char, delete-char-forward, XF_ARG) FN(del_char, "delete-char-forward", XF_ARG)
FN(del_fword, delete-word-forward, XF_ARG) FN(del_fword, "delete-word-forward", XF_ARG)
FN(del_line, kill-line, 0) FN(del_line, "kill-line", 0)
FN(draw_line, redraw, 0) FN(draw_line, "redraw", 0)
#ifndef MKSH_SMALL #ifndef MKSH_SMALL
FN(edit_line, edit-line, XF_ARG) FN(edit_line, "edit-line", XF_ARG)
#endif #endif
FN(end_hist, end-of-history, 0) FN(end_hist, "end-of-history", 0)
FN(end_of_text, eot, 0) FN(end_of_text, "eot", 0)
FN(enumerate, list, 0) FN(enumerate, "list", 0)
FN(eot_del, eot-or-delete, XF_ARG) FN(eot_del, "eot-or-delete", XF_ARG)
FN(error, error, 0) FN(error, "error", 0)
FN(expand, expand-file, 0) FN(expand, "expand-file", 0)
#ifndef MKSH_SMALL #ifndef MKSH_SMALL
FN(fold_capitalise, capitalize-word, XF_ARG) FN(fold_capitalise, "capitalize-word", XF_ARG)
FN(fold_lower, downcase-word, XF_ARG) 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 #ifndef MKSH_SMALL
FN(ins_string, macro-string, XF_NOBIND) FN(ins_string, "macro-string", XF_NOBIND)
#endif #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)
FN(list_comm, list-command, 0) FN(list_comm, "list-command", 0)
FN(list_file, list-file, 0) FN(list_file, "list-file", 0)
FN(literal, quote, 0) FN(literal, "quote", 0)
FN(meta1, prefix-1, XF_PREFIX) FN(meta1, "prefix-1", XF_PREFIX)
FN(meta2, prefix-2, XF_PREFIX) FN(meta2, "prefix-2", XF_PREFIX)
FN(meta_yank, yank-pop, 0) FN(meta_yank, "yank-pop", 0)
FN(mv_back, backward-char, XF_ARG) FN(mv_back, "backward-char", XF_ARG)
FN(mv_begin, beginning-of-line, 0) FN(mv_begin, "beginning-of-line", 0)
FN(mv_bword, backward-word, XF_ARG) FN(mv_bword, "backward-word", XF_ARG)
FN(mv_end, end-of-line, 0) FN(mv_end, "end-of-line", 0)
FN(mv_forw, forward-char, XF_ARG) FN(mv_forw, "forward-char", XF_ARG)
FN(mv_fword, forward-word, XF_ARG) FN(mv_fword, "forward-word", XF_ARG)
FN(newline, newline, 0) FN(newline, "newline", 0)
FN(next_com, down-history, XF_ARG) FN(next_com, "down-history", XF_ARG)
FN(nl_next_com, newline-and-next, 0) FN(nl_next_com, "newline-and-next", 0)
FN(noop, no-op, 0) FN(noop, "no-op", 0)
FN(prev_com, up-history, XF_ARG) FN(prev_com, "up-history", XF_ARG)
FN(prev_histword, prev-hist-word, XF_ARG) FN(prev_histword, "prev-hist-word", XF_ARG)
FN(search_char_back, search-character-backward, XF_ARG) FN(search_char_back, "search-character-backward", XF_ARG)
FN(search_char_forw, search-character-forward, XF_ARG) FN(search_char_forw, "search-character-forward", XF_ARG)
FN(search_hist, search-history, 0) FN(search_hist, "search-history", 0)
#ifndef MKSH_SMALL #ifndef MKSH_SMALL
FN(search_hist_dn, search-history-down, 0) FN(search_hist_dn, "search-history-down", 0)
FN(search_hist_up, search-history-up, 0) FN(search_hist_up, "search-history-up", 0)
#endif #endif
FN(set_arg, set-arg, XF_NOBIND) FN(set_arg, "set-arg", XF_NOBIND)
FN(set_mark, set-mark-command, 0) FN(set_mark, "set-mark-command", 0)
FN(transpose, transpose-chars, 0) FN(transpose, "transpose-chars", 0)
FN(version, version, 0) FN(version, "version", 0)
#ifndef MKSH_SMALL #ifndef MKSH_SMALL
FN(vt_hack, vt100-hack, XF_ARG) FN(vt_hack, "vt100-hack", XF_ARG)
#endif #endif
FN(xchg_point_mark, exchange-point-and-mark, 0) FN(xchg_point_mark, "exchange-point-and-mark", 0)
FN(yank, yank, 0) FN(yank, "yank", 0)
#undef FN #undef FN
#undef F0 #undef F0

18
eval.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.89 2010/05/16 19:17:42 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.90 2010/07/17 22:09:33 tg Exp $");
/* /*
* string expansion * string expansion
@ -1559,19 +1559,19 @@ alt_expand(XPtrV *wp, char *start, char *exp_start, char *end, int fdo)
count++; count++;
else if ((*p == CBRACE && --count == 0) || else if ((*p == CBRACE && --count == 0) ||
(*p == ',' && count == 1)) { (*p == ',' && count == 1)) {
char *new; char *news;
int l1, l2, l3; int l1, l2, l3;
l1 = brace_start - start; l1 = brace_start - start;
l2 = (p - 1) - field_start; l2 = (p - 1) - field_start;
l3 = end - brace_end; l3 = end - brace_end;
new = alloc(l1 + l2 + l3 + 1, ATEMP); news = alloc(l1 + l2 + l3 + 1, ATEMP);
memcpy(new, start, l1); memcpy(news, start, l1);
memcpy(new + l1, field_start, l2); memcpy(news + l1, field_start, l2);
memcpy(new + l1 + l2, brace_end, l3); memcpy(news + l1 + l2, brace_end, l3);
new[l1 + l2 + l3] = '\0'; news[l1 + l2 + l3] = '\0';
alt_expand(wp, new, new + l1, alt_expand(wp, news, news + l1,
new + l1 + l2 + l3, fdo); news + l1 + l2 + l3, fdo);
field_start = p + 1; field_start = p + 1;
} }
} }

21
exec.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.74 2010/04/08 13:21:05 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/exec.c,v 1.75 2010/07/17 22:09:34 tg Exp $");
#ifndef MKSH_DEFAULT_EXECSHELL #ifndef MKSH_DEFAULT_EXECSHELL
#define MKSH_DEFAULT_EXECSHELL "/bin/sh" #define MKSH_DEFAULT_EXECSHELL "/bin/sh"
@ -35,7 +35,7 @@ static int call_builtin(struct tbl *, const char **);
static int iosetup(struct ioword *, struct tbl *); static int iosetup(struct ioword *, struct tbl *);
static int herein(const char *, int); static int herein(const char *, int);
static const char *do_selectargs(const char **, bool); static const char *do_selectargs(const char **, bool);
static int dbteste_isa(Test_env *, Test_meta); static Test_op dbteste_isa(Test_env *, Test_meta);
static const char *dbteste_getopnd(Test_env *, Test_op, bool); static const char *dbteste_getopnd(Test_env *, Test_op, bool);
static void dbteste_error(Test_env *, int, const char *); static void dbteste_error(Test_env *, int, const char *);
@ -1446,19 +1446,20 @@ pr_list(char * const *ap)
* [[ ... ]] evaluation routines * [[ ... ]] evaluation routines
*/ */
/* Test if the current token is a whatever. Accepts the current token if /*
* Test if the current token is a whatever. Accepts the current token if
* it is. Returns 0 if it is not, non-zero if it is (in the case of * it is. Returns 0 if it is not, non-zero if it is (in the case of
* TM_UNOP and TM_BINOP, the returned value is a Test_op). * TM_UNOP and TM_BINOP, the returned value is a Test_op).
*/ */
static int static Test_op
dbteste_isa(Test_env *te, Test_meta meta) dbteste_isa(Test_env *te, Test_meta meta)
{ {
int ret = 0; Test_op ret = TO_NONOP;
int uqword; int uqword;
const char *p; const char *p;
if (!*te->pos.wp) if (!*te->pos.wp)
return (meta == TM_END); return (meta == TM_END ? TO_NONNULL : TO_NONOP);
/* unquoted word? */ /* unquoted word? */
for (p = *te->pos.wp; *p == CHAR; p += 2) for (p = *te->pos.wp; *p == CHAR; p += 2)
@ -1476,13 +1477,13 @@ dbteste_isa(Test_env *te, Test_meta meta)
ret = test_isop(meta, buf); ret = test_isop(meta, buf);
} }
} else if (meta == TM_END) } else if (meta == TM_END)
ret = 0; ret = TO_NONOP;
else else
ret = uqword && ret = (uqword && !strcmp(*te->pos.wp,
strcmp(*te->pos.wp, dbtest_tokens[(int) meta]) == 0; dbtest_tokens[(int)meta])) ? TO_NONNULL : TO_NONOP;
/* Accept the token? */ /* Accept the token? */
if (ret) if (ret != TO_NONOP)
te->pos.wp++; te->pos.wp++;
return (ret); return (ret);

32
funcs.c
View File

@ -25,7 +25,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.155 2010/04/27 21:39:08 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.156 2010/07/17 22:09:34 tg Exp $");
#if HAVE_KILLPG #if HAVE_KILLPG
/* /*
@ -168,7 +168,7 @@ static int test_oexpr(Test_env *, bool);
static int test_aexpr(Test_env *, bool); static int test_aexpr(Test_env *, bool);
static int test_nexpr(Test_env *, bool); static int test_nexpr(Test_env *, bool);
static int test_primary(Test_env *, bool); static int test_primary(Test_env *, bool);
static int ptest_isa(Test_env *, Test_meta); static Test_op ptest_isa(Test_env *, Test_meta);
static const char *ptest_getopnd(Test_env *, Test_op, bool); static const char *ptest_getopnd(Test_env *, Test_op, bool);
static void ptest_error(Test_env *, int, const char *); static void ptest_error(Test_env *, int, const char *);
static char *kill_fmt_entry(char *, int, int, const void *); static char *kill_fmt_entry(char *, int, int, const void *);
@ -336,7 +336,7 @@ c_cd(const char **wp)
bool printpath = false; /* print where we cd'd? */ bool printpath = false; /* print where we cd'd? */
struct tbl *pwd_s, *oldpwd_s; struct tbl *pwd_s, *oldpwd_s;
XString xs; XString xs;
char *dir, *allocd = NULL, *try, *pwd, *cdpath; char *dir, *allocd = NULL, *tryp, *pwd, *cdpath;
while ((optc = ksh_getopt(wp, &builtin_opt, "LP")) != -1) while ((optc = ksh_getopt(wp, &builtin_opt, "LP")) != -1)
switch (optc) { switch (optc) {
@ -421,10 +421,10 @@ c_cd(const char **wp)
do { do {
cdnode = make_path(current_wd, dir, &cdpath, &xs, &phys_path); cdnode = make_path(current_wd, dir, &cdpath, &xs, &phys_path);
if (physical) if (physical)
rv = chdir(try = Xstring(xs, xp) + phys_path); rv = chdir(tryp = Xstring(xs, xp) + phys_path);
else { else {
simplify_path(Xstring(xs, xp)); simplify_path(Xstring(xs, xp));
rv = chdir(try = Xstring(xs, xp)); rv = chdir(tryp = Xstring(xs, xp));
} }
} while (rv < 0 && cdpath != NULL); } while (rv < 0 && cdpath != NULL);
@ -432,7 +432,7 @@ c_cd(const char **wp)
if (cdnode) if (cdnode)
bi_errorf("%s: bad directory", dir); bi_errorf("%s: bad directory", dir);
else else
bi_errorf("%s - %s", try, strerror(errno)); bi_errorf("%s - %s", tryp, strerror(errno));
afree(allocd, ATEMP); afree(allocd, ATEMP);
return (1); return (1);
} }
@ -2633,11 +2633,11 @@ c_mknod(const char **wp)
goto c_mknod_err; goto c_mknod_err;
} }
dv = makedev(majnum, minnum); dv = makedev(majnum, minnum);
if ((unsigned long)major(dv) != majnum) { if ((unsigned long)(major(dv)) != majnum) {
bi_errorf("device major too large: %lu", majnum); bi_errorf("device major too large: %lu", majnum);
goto c_mknod_err; goto c_mknod_err;
} }
if ((unsigned long)minor(dv) != minnum) { if ((unsigned long)(minor(dv)) != minnum) {
bi_errorf("device minor too large: %lu", minnum); bi_errorf("device minor too large: %lu", minnum);
goto c_mknod_err; goto c_mknod_err;
} }
@ -3048,31 +3048,33 @@ test_primary(Test_env *te, bool do_eval)
* Plain test (test and [ .. ]) specific routines. * Plain test (test and [ .. ]) specific routines.
*/ */
/* Test if the current token is a whatever. Accepts the current token if /*
* Test if the current token is a whatever. Accepts the current token if
* it is. Returns 0 if it is not, non-zero if it is (in the case of * it is. Returns 0 if it is not, non-zero if it is (in the case of
* TM_UNOP and TM_BINOP, the returned value is a Test_op). * TM_UNOP and TM_BINOP, the returned value is a Test_op).
*/ */
static int static Test_op
ptest_isa(Test_env *te, Test_meta meta) ptest_isa(Test_env *te, Test_meta meta)
{ {
/* Order important - indexed by Test_meta values */ /* Order important - indexed by Test_meta values */
static const char *const tokens[] = { static const char *const tokens[] = {
"-o", "-a", "!", "(", ")" "-o", "-a", "!", "(", ")"
}; };
int rv; Test_op rv;
if (te->pos.wp >= te->wp_end) if (te->pos.wp >= te->wp_end)
return (meta == TM_END); return (meta == TM_END ? TO_NONNULL : TO_NONOP);
if (meta == TM_UNOP || meta == TM_BINOP) if (meta == TM_UNOP || meta == TM_BINOP)
rv = test_isop(meta, *te->pos.wp); rv = test_isop(meta, *te->pos.wp);
else if (meta == TM_END) else if (meta == TM_END)
rv = 0; rv = TO_NONOP;
else else
rv = strcmp(*te->pos.wp, tokens[(int) meta]) == 0; rv = !strcmp(*te->pos.wp, tokens[(int)meta]) ?
TO_NONNULL : TO_NONOP;
/* Accept the token? */ /* Accept the token? */
if (rv) if (rv != TO_NONOP)
te->pos.wp++; te->pos.wp++;
return (rv); return (rv);

View File

@ -26,7 +26,7 @@
#include <sys/file.h> #include <sys/file.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.96 2010/07/04 17:45:14 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.97 2010/07/17 22:09:35 tg Exp $");
/*- /*-
* MirOS: This is the default mapping type, and need not be specified. * MirOS: This is the default mapping type, and need not be specified.
@ -956,7 +956,7 @@ writehistfile(int lno, char *cmd)
{ {
int sizenow; int sizenow;
unsigned char *base; unsigned char *base;
unsigned char *new; unsigned char *news;
int bytes; int bytes;
unsigned char hdr[5]; unsigned char hdr[5];
@ -973,13 +973,13 @@ writehistfile(int lno, char *cmd)
MAP_FILE | MAP_PRIVATE, histfd, (off_t)0); MAP_FILE | MAP_PRIVATE, histfd, (off_t)0);
if (base == (unsigned char *)MAP_FAILED) if (base == (unsigned char *)MAP_FAILED)
goto bad; goto bad;
new = base + hsize; news = base + hsize;
if (*new != COMMAND) { if (*news != COMMAND) {
munmap((caddr_t)base, sizenow); munmap((caddr_t)base, sizenow);
goto bad; goto bad;
} }
hist_source->line--; hist_source->line--;
histload(hist_source, new, bytes); histload(hist_source, news, bytes);
hist_source->line++; hist_source->line++;
lno = hist_source->line; lno = hist_source->line;
munmap((caddr_t)base, sizenow); munmap((caddr_t)base, sizenow);

12
lex.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.115 2010/07/04 18:29:40 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/lex.c,v 1.116 2010/07/17 22:09:36 tg Exp $");
/* /*
* states while lexing word * states while lexing word
@ -1748,12 +1748,12 @@ getsc_bn(void)
static Lex_state * static Lex_state *
push_state_(State_info *si, Lex_state *old_end) push_state_(State_info *si, Lex_state *old_end)
{ {
Lex_state *new = alloc(STATE_BSIZE * sizeof(Lex_state), ATEMP); Lex_state *news = alloc(STATE_BSIZE * sizeof(Lex_state), ATEMP);
new[0].ls_info.base = old_end; news[0].ls_info.base = old_end;
si->base = &new[0]; si->base = &news[0];
si->end = &new[STATE_BSIZE]; si->end = &news[STATE_BSIZE];
return (&new[1]); return (&news[1]);
} }
static Lex_state * static Lex_state *

8
misc.c
View File

@ -29,7 +29,7 @@
#include <grp.h> #include <grp.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.140 2010/07/13 13:07:56 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/misc.c,v 1.141 2010/07/17 22:09:36 tg Exp $");
unsigned char chtypes[UCHAR_MAX + 1]; /* type bits for unsigned char */ unsigned char chtypes[UCHAR_MAX + 1]; /* type bits for unsigned char */
@ -695,10 +695,10 @@ do_gmatch(const unsigned char *s, const unsigned char *se,
static const unsigned char * static const unsigned char *
cclass(const unsigned char *p, int sub) cclass(const unsigned char *p, int sub)
{ {
int c, d, not, found = 0; int c, d, notp, found = 0;
const unsigned char *orig_p = p; const unsigned char *orig_p = p;
if ((not = (ISMAGIC(*p) && *++p == NOT))) if ((notp = (ISMAGIC(*p) && *++p == NOT)))
p++; p++;
do { do {
c = *p++; c = *p++;
@ -732,7 +732,7 @@ cclass(const unsigned char *p, int sub)
found = 1; found = 1;
} while (!(ISMAGIC(p[0]) && p[1] == ']')); } while (!(ISMAGIC(p[0]) && p[1] == ']'));
return ((found != not) ? p+2 : NULL); return ((found != notp) ? p+2 : NULL);
} }
/* Look for next ) or | (if match_sep) in *(foo|bar) pattern */ /* Look for next ) or | (if match_sep) in *(foo|bar) pattern */

10
mksh.1
View File

@ -1,4 +1,4 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.231 2010/07/17 20:21:18 tg Exp $ .\" $MirOS: src/bin/mksh/mksh.1,v 1.232 2010/07/17 22:09:37 tg Exp $
.\" $OpenBSD: ksh.1,v 1.136 2010/07/15 20:04:35 schwarze Exp $ .\" $OpenBSD: ksh.1,v 1.136 2010/07/15 20:04:35 schwarze Exp $
.\"- .\"-
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
@ -3509,14 +3509,14 @@ option suppresses the trailing newline.
.Pp .Pp
.It Ic printf Ar format Op Ar arguments ... .It Ic printf Ar format Op Ar arguments ...
Formatted output. Formatted output.
The same as the utility Approximately the same as the utility
.Xr printf 1 , .Xr printf 1 ,
except that it may use the same except that it uses the same
.Sx Backslash expansion .Sx Backslash expansion
code as the rest of and I/O code as the rest of
.Nm mksh . .Nm mksh .
This is not normally part of This is not normally part of
.Nm mksh , .Nm mksh ;
however, distributors may have added this as builtin as a speed hack. however, distributors may have added this as builtin as a speed hack.
.Pp .Pp
.It Ic pwd Op Fl LP .It Ic pwd Op Fl LP

25
sh.h
View File

@ -150,9 +150,9 @@
#endif #endif
#ifdef EXTERN #ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.397 2010/07/13 13:12:32 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.398 2010/07/17 22:09:38 tg Exp $");
#endif #endif
#define MKSH_VERSION "R39 2010/07/13" #define MKSH_VERSION "R39 2010/07/17"
#ifndef MKSH_INCLUDES_ONLY #ifndef MKSH_INCLUDES_ONLY
@ -548,7 +548,7 @@ extern struct env {
* some kind of global shell state, for change_random() mostly * some kind of global shell state, for change_random() mostly
*/ */
EXTERN struct { EXTERN struct mksh_kshstate_v {
/* for change_random */ /* for change_random */
struct timeval cr_tv; /* timestamp */ struct timeval cr_tv; /* timestamp */
const void *cr_dp; /* argument address */ const void *cr_dp; /* argument address */
@ -561,7 +561,7 @@ EXTERN struct {
struct env env_; /* top-level parsing & execution env. */ struct env env_; /* top-level parsing & execution env. */
uint8_t shell_flags_[FNFLAGS]; uint8_t shell_flags_[FNFLAGS];
} kshstate_v; } kshstate_v;
EXTERN struct { EXTERN struct mksh_kshstate_f {
const char *kshname_; /* $0 */ const char *kshname_; /* $0 */
pid_t kshpid_; /* $$, shell PID */ pid_t kshpid_; /* $$, shell PID */
pid_t kshpgrp_; /* process group of shell */ pid_t kshpgrp_; /* process group of shell */
@ -1666,7 +1666,9 @@ enum Test_op {
TO_FILRD, TO_FILGZ, TO_FILTT, TO_FILSETU, TO_FILWR, TO_FILEX, TO_FILRD, TO_FILGZ, TO_FILTT, TO_FILSETU, TO_FILWR, TO_FILEX,
/* binary operators */ /* binary operators */
TO_STEQL, TO_STNEQ, TO_STLT, TO_STGT, TO_INTEQ, TO_INTNE, TO_INTGT, TO_STEQL, TO_STNEQ, TO_STLT, TO_STGT, TO_INTEQ, TO_INTNE, TO_INTGT,
TO_INTGE, TO_INTLT, TO_INTLE, TO_FILEQ, TO_FILNT, TO_FILOT TO_INTGE, TO_INTLT, TO_INTLE, TO_FILEQ, TO_FILNT, TO_FILOT,
/* not an operator */
TO_NONNULL /* !TO_NONOP */
}; };
typedef enum Test_op Test_op; typedef enum Test_op Test_op;
@ -1686,19 +1688,18 @@ typedef enum Test_meta Test_meta;
#define TEF_ERROR BIT(0) /* set if we've hit an error */ #define TEF_ERROR BIT(0) /* set if we've hit an error */
#define TEF_DBRACKET BIT(1) /* set if [[ .. ]] test */ #define TEF_DBRACKET BIT(1) /* set if [[ .. ]] test */
typedef struct test_env Test_env; typedef struct test_env {
struct test_env {
union { union {
const char **wp;/* used by ptest_* */ const char **wp;/* used by ptest_* */
XPtrV *av; /* used by dbtestp_* */ XPtrV *av; /* used by dbtestp_* */
} pos; } pos;
const char **wp_end; /* used by ptest_* */ const char **wp_end; /* used by ptest_* */
int (*isa)(Test_env *, Test_meta); Test_op (*isa)(struct test_env *, Test_meta);
const char *(*getopnd) (Test_env *, Test_op, bool); const char *(*getopnd) (struct test_env *, Test_op, bool);
int (*eval)(Test_env *, Test_op, const char *, const char *, bool); int (*eval)(struct test_env *, Test_op, const char *, const char *, bool);
void (*error)(Test_env *, int, const char *); void (*error)(struct test_env *, int, const char *);
int flags; /* TEF_* */ int flags; /* TEF_* */
}; } Test_env;
extern const char *const dbtest_tokens[]; extern const char *const dbtest_tokens[];

29
syn.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.48 2009/12/12 22:27:10 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/syn.c,v 1.49 2010/07/17 22:09:39 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) */
@ -50,7 +50,7 @@ static void nesting_push(struct nesting_state *, int);
static void nesting_pop(struct nesting_state *); static void nesting_pop(struct nesting_state *);
static int assign_command(char *); static int assign_command(char *);
static int inalias(struct source *); static int inalias(struct source *);
static int dbtestp_isa(Test_env *, Test_meta); static Test_op dbtestp_isa(Test_env *, Test_meta);
static const char *dbtestp_getopnd(Test_env *, Test_op, bool); static const char *dbtestp_getopnd(Test_env *, Test_op, bool);
static int dbtestp_eval(Test_env *, Test_op, const char *, static int dbtestp_eval(Test_env *, Test_op, const char *,
const char *, bool); const char *, bool);
@ -917,42 +917,45 @@ const char db_close[] = { CHAR, ']', CHAR, ']', EOS };
const char db_lthan[] = { CHAR, '<', EOS }; const char db_lthan[] = { CHAR, '<', EOS };
const char db_gthan[] = { CHAR, '>', EOS }; const char db_gthan[] = { CHAR, '>', EOS };
/* Test if the current token is a whatever. Accepts the current token if /*
* Test if the current token is a whatever. Accepts the current token if
* it is. Returns 0 if it is not, non-zero if it is (in the case of * it is. Returns 0 if it is not, non-zero if it is (in the case of
* TM_UNOP and TM_BINOP, the returned value is a Test_op). * TM_UNOP and TM_BINOP, the returned value is a Test_op).
*/ */
static int static Test_op
dbtestp_isa(Test_env *te, Test_meta meta) dbtestp_isa(Test_env *te, Test_meta meta)
{ {
int c = tpeek(ARRAYVAR | (meta == TM_BINOP ? 0 : CONTIN)); int c = tpeek(ARRAYVAR | (meta == TM_BINOP ? 0 : CONTIN));
int uqword; int uqword;
char *save = NULL; char *save = NULL;
int ret = 0; Test_op ret = TO_NONOP;
/* unquoted word? */ /* unquoted word? */
uqword = c == LWORD && *ident; uqword = c == LWORD && *ident;
if (meta == TM_OR) if (meta == TM_OR)
ret = c == LOGOR; ret = c == LOGOR ? TO_NONNULL : TO_NONOP;
else if (meta == TM_AND) else if (meta == TM_AND)
ret = c == LOGAND; ret = c == LOGAND ? TO_NONNULL : TO_NONOP;
else if (meta == TM_NOT) else if (meta == TM_NOT)
ret = uqword && strcmp(yylval.cp, dbtest_tokens[(int) TM_NOT]) == 0; ret = (uqword && !strcmp(yylval.cp,
dbtest_tokens[(int)TM_NOT])) ? TO_NONNULL : TO_NONOP;
else if (meta == TM_OPAREN) else if (meta == TM_OPAREN)
ret = c == '(' /*)*/; ret = c == '(' /*)*/ ? TO_NONNULL : TO_NONOP;
else if (meta == TM_CPAREN) else if (meta == TM_CPAREN)
ret = c == /*(*/ ')'; ret = c == /*(*/ ')' ? TO_NONNULL : TO_NONOP;
else if (meta == TM_UNOP || meta == TM_BINOP) { else if (meta == TM_UNOP || meta == TM_BINOP) {
if (meta == TM_BINOP && c == REDIR && if (meta == TM_BINOP && c == REDIR &&
(yylval.iop->flag == IOREAD || yylval.iop->flag == IOWRITE)) { (yylval.iop->flag == IOREAD || yylval.iop->flag == IOWRITE)) {
ret = 1; ret = TO_NONNULL;
save = wdcopy(yylval.iop->flag == IOREAD ? save = wdcopy(yylval.iop->flag == IOREAD ?
db_lthan : db_gthan, ATEMP); db_lthan : db_gthan, ATEMP);
} else if (uqword && (ret = test_isop(meta, ident))) } else if (uqword && (ret = test_isop(meta, ident)))
save = yylval.cp; save = yylval.cp;
} else /* meta == TM_END */ } else /* meta == TM_END */
ret = uqword && strcmp(yylval.cp, db_close) == 0; ret = (uqword && !strcmp(yylval.cp,
if (ret) { db_close)) ? TO_NONNULL : TO_NONOP;
if (ret != TO_NONOP) {
ACCEPT; ACCEPT;
if (meta < NELEM(dbtest_tokens)) if (meta < NELEM(dbtest_tokens))
save = wdcopy(dbtest_tokens[(int)meta], ATEMP); save = wdcopy(dbtest_tokens[(int)meta], ATEMP);

40
var.c
View File

@ -26,7 +26,7 @@
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.107 2010/07/11 11:17:33 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/var.c,v 1.108 2010/07/17 22:09:40 tg Exp $");
/* /*
* Variables * Variables
@ -40,7 +40,7 @@ __RCSID("$MirOS: src/bin/mksh/var.c,v 1.107 2010/07/11 11:17:33 tg Exp $");
static struct tbl vtemp; static struct tbl vtemp;
static struct table specials; static struct table specials;
static char *formatstr(struct tbl *, const char *); static char *formatstr(struct tbl *, const char *);
static void export(struct tbl *, const char *); static void exportprep(struct tbl *, const char *);
static int special(const char *); static int special(const char *);
static void unspecial(const char *); static void unspecial(const char *);
static void getspec(struct tbl *); static void getspec(struct tbl *);
@ -426,7 +426,7 @@ setstr(struct tbl *vq, const char *s, int error_ok)
if (s && (vq->flag & (UCASEV_AL|LCASEV|LJUST|RJUST))) if (s && (vq->flag & (UCASEV_AL|LCASEV|LJUST|RJUST)))
s = salloc = formatstr(vq, s); s = salloc = formatstr(vq, s);
if ((vq->flag&EXPORT)) if ((vq->flag&EXPORT))
export(vq, s); exportprep(vq, s);
else { else {
strdupx(vq->val.s, s, vq->areap); strdupx(vq->val.s, s, vq->areap);
vq->flag |= ALLOC; vq->flag |= ALLOC;
@ -645,7 +645,7 @@ formatstr(struct tbl *vp, const char *s)
* make vp->val.s be "name=value" for quick exporting. * make vp->val.s be "name=value" for quick exporting.
*/ */
static void static void
export(struct tbl *vp, const char *val) exportprep(struct tbl *vp, const char *val)
{ {
char *xp; char *xp;
char *op = (vp->flag&ALLOC) ? vp->val.s : NULL; char *op = (vp->flag&ALLOC) ? vp->val.s : NULL;
@ -837,7 +837,7 @@ typeset(const char *var, Tflag set, Tflag clr, int field, int base)
/* only x[0] is ever exported, so use vpbase */ /* only x[0] is ever exported, so use vpbase */
if ((vpbase->flag&EXPORT) && !(vpbase->flag&INTEGER) && if ((vpbase->flag&EXPORT) && !(vpbase->flag&INTEGER) &&
vpbase->type == 0) vpbase->type == 0)
export(vpbase, (vpbase->flag&ISSET) ? vpbase->val.s : null); exportprep(vpbase, (vpbase->flag&ISSET) ? vpbase->val.s : null);
return (vp); return (vp);
} }
@ -1288,7 +1288,7 @@ unsetspec(struct tbl *vp)
static struct tbl * static struct tbl *
arraysearch(struct tbl *vp, uint32_t val) arraysearch(struct tbl *vp, uint32_t val)
{ {
struct tbl *prev, *curr, *new; struct tbl *prev, *curr, *news;
size_t len; size_t len;
vp->flag = (vp->flag | (ARRAY|DEFINED)) & ~ASSOC; vp->flag = (vp->flag | (ARRAY|DEFINED)) & ~ASSOC;
@ -1304,25 +1304,25 @@ arraysearch(struct tbl *vp, uint32_t val)
if (curr && curr->ua.index == val) { if (curr && curr->ua.index == val) {
if (curr->flag&ISSET) if (curr->flag&ISSET)
return (curr); return (curr);
new = curr; news = curr;
} else } else
new = NULL; news = NULL;
len = strlen(vp->name) + 1; len = strlen(vp->name) + 1;
if (!new) { if (!news) {
new = alloc(offsetof(struct tbl, name[0]) + len, vp->areap); news = alloc(offsetof(struct tbl, name[0]) + len, vp->areap);
memcpy(new->name, vp->name, len); memcpy(news->name, vp->name, len);
} }
new->flag = (vp->flag & ~(ALLOC|DEFINED|ISSET|SPECIAL)) | AINDEX; news->flag = (vp->flag & ~(ALLOC|DEFINED|ISSET|SPECIAL)) | AINDEX;
new->type = vp->type; news->type = vp->type;
new->areap = vp->areap; news->areap = vp->areap;
new->u2.field = vp->u2.field; news->u2.field = vp->u2.field;
new->ua.index = val; news->ua.index = val;
if (curr != new) { /* not reusing old array entry */ if (curr != news) { /* not reusing old array entry */
prev->u.array = new; prev->u.array = news;
new->u.array = curr; news->u.array = curr;
} }
return (new); return (news);
} }
/* Return the length of an array reference (eg, [1+2]) - cp is assumed /* Return the length of an array reference (eg, [1+2]) - cp is assumed