• remove strcasestr.c, use home-grown implementation¹, call it stricmp,

and have it return an API-correct const char *
• enhance and stylify comments
• a little KNF and simplifications
• #ifdef DEBUG: replace strchr and strstr with ucstrchr and ucstrstr
  that take and return a non-const char *, and fix the violations
• new cstrchr, cstrstr (take and give const char *)
• new vstrchr, vstrstr (take const or not, give boolean value)
• new afreechk(x) = afreechv(x,x) = if (x1) afree(x2, ATEMP)
• new ksh_isdash(str) = (str != NULL) && !strcmp(str, "-")
• replace the only use of strrchr with inlined code to shrink
• minor man page fixes
• Minix 3 signames are autogenerated with gcc
• rename strlfun.c to strlcpy.c since we don't do strlcat(3) anyway,
  only strlcpy(3), and shorten it
• dot.mkshrc: move MKSH=… down to the export line
  to not disturb the PS1 visual impression ☺
• dot.mkshrc: Lstripcom(): optimise
• bump version

¹) side effect from creating API-correct cstrchr, cstrstr, etc.
   uses goto so it must be better ☻

tested on mirbsd-current via both Makefile and Build.sh
This commit is contained in:
tg 2007-03-04 03:04:28 +00:00
parent 62b347a1b0
commit 83c2ee87f4
25 changed files with 332 additions and 340 deletions

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# $MirOS: src/bin/mksh/Build.sh,v 1.154 2007/03/03 21:36:06 tg Exp $ # $MirOS: src/bin/mksh/Build.sh,v 1.155 2007/03/04 03:04:22 tg Exp $
#- #-
# Env: CC, CFLAGS, CPP, CPPFLAGS, LDFLAGS, LIBS, NOWARN, NROFF, TARGET_OS # Environment used: CC CFLAGS CPP CPPFLAGS LDFLAGS LIBS NOWARN NROFF TARGET_OS
# CPPFLAGS recognised: MKSH_SMALL MKSH_ASSUME_UTF8 MKSH_NEED_MKNOD MKSH_NOPWNAM # CPPFLAGS recognised: MKSH_SMALL MKSH_ASSUME_UTF8 MKSH_NEED_MKNOD MKSH_NOPWNAM
v() v()
@ -597,8 +597,7 @@ if test 1 = $NEED_MKSH_SIGNAME; then
fi fi
addsrcs HAVE_SETMODE setmode.c addsrcs HAVE_SETMODE setmode.c
addsrcs HAVE_STRCASESTR strcasestr.c addsrcs HAVE_STRLCPY strlcpy.c
addsrcs HAVE_STRLCPY strlfun.c
CPPFLAGS="$CPPFLAGS -DHAVE_CONFIG_H -DCONFIG_H_FILENAME=\\\"sh.h\\\"" CPPFLAGS="$CPPFLAGS -DHAVE_CONFIG_H -DCONFIG_H_FILENAME=\\\"sh.h\\\""
case $s:$HAVE_MKSH_NOPAM in case $s:$HAVE_MKSH_NOPAM in

View File

@ -1,4 +1,6 @@
# $MirOS: src/bin/mksh/Makefile,v 1.33 2007/03/04 00:13:14 tg Exp $ # $MirOS: src/bin/mksh/Makefile,v 1.34 2007/03/04 03:04:23 tg Exp $
#-
# use CPPFLAGS=-DDEBUG __CRAZY=Yes to check for certain more stuff
.include <bsd.own.mk> .include <bsd.own.mk>

20
alloc.c
View File

@ -29,7 +29,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/alloc.c,v 1.3 2005/11/22 18:40:40 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/alloc.c,v 1.4 2007/03/04 03:04:23 tg Exp $");
struct link { struct link {
struct link *prev; struct link *prev;
@ -40,7 +40,7 @@ Area *
ainit(Area *ap) ainit(Area *ap)
{ {
ap->freelist = NULL; ap->freelist = NULL;
return ap; return (ap);
} }
void void
@ -55,16 +55,15 @@ afreeall(Area *ap)
ap->freelist = NULL; ap->freelist = NULL;
} }
#define L2P(l) ( (void *)(((char *)(l)) + sizeof(struct link)) ) #define L2P(l) ( (void *)(((char *)(l)) + sizeof (struct link)) )
#define P2L(p) ( (struct link *)(((char *)(p)) - sizeof(struct link)) ) #define P2L(p) ( (struct link *)(((char *)(p)) - sizeof (struct link)) )
void * void *
alloc(size_t size, Area *ap) alloc(size_t size, Area *ap)
{ {
struct link *l; struct link *l;
l = malloc(sizeof(struct link) + size); if ((l = malloc(sizeof (struct link) + size)) == NULL)
if (l == NULL)
internal_errorf(1, "unable to allocate memory"); internal_errorf(1, "unable to allocate memory");
l->next = ap->freelist; l->next = ap->freelist;
l->prev = NULL; l->prev = NULL;
@ -72,7 +71,7 @@ alloc(size_t size, Area *ap)
ap->freelist->prev = l; ap->freelist->prev = l;
ap->freelist = l; ap->freelist = l;
return L2P(l); return (L2P(l));
} }
void * void *
@ -81,14 +80,13 @@ aresize(void *ptr, size_t size, Area *ap)
struct link *l, *l2, *lprev, *lnext; struct link *l, *l2, *lprev, *lnext;
if (ptr == NULL) if (ptr == NULL)
return alloc(size, ap); return (alloc(size, ap));
l = P2L(ptr); l = P2L(ptr);
lprev = l->prev; lprev = l->prev;
lnext = l->next; lnext = l->next;
l2 = realloc(l, sizeof(struct link) + size); if ((l2 = realloc(l, sizeof (struct link) + size)) == NULL)
if (l2 == NULL)
internal_errorf(1, "unable to allocate memory"); internal_errorf(1, "unable to allocate memory");
if (lprev) if (lprev)
lprev->next = l2; lprev->next = l2;
@ -97,7 +95,7 @@ aresize(void *ptr, size_t size, Area *ap)
if (lnext) if (lnext)
lnext->prev = l2; lnext->prev = l2;
return L2P(l2); return (L2P(l2));
} }
void void

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.91 2007/02/16 17:46:41 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.92 2007/03/04 03:04:23 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 $
@ -7,7 +7,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 R29 2007/02/16 @(#)MIRBSD KSH R29 2007/03/04
description: description:
Check version of shell. Check version of shell.
category: pdksh category: pdksh

View File

@ -1,9 +1,9 @@
$MirOS: src/bin/mksh/copyright,v 1.19 2007/01/17 01:24:29 tg Exp $ $MirOS: src/bin/mksh/copyright,v 1.20 2007/03/04 03:04:23 tg Rel $
The MirBSD Korn Shell (mksh) is The MirBSD Korn Shell (mksh) is
Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
Thorsten Glaser <tg@mirbsd.de> Thorsten "mirabilos" Glaser <tg@mirbsd.de>
Provided that these terms and disclaimer and all copyright notices Provided that these terms and disclaimer and all copyright notices
are retained or reproduced in an accompanying document, permission are retained or reproduced in an accompanying document, permission
@ -33,4 +33,4 @@ A number of files that are either always or conditionally included
during compilation, depending on the target operating environment, during compilation, depending on the target operating environment,
are covered by different (2/3-clause BSD or similar) licences; re- are covered by different (2/3-clause BSD or similar) licences; re-
fer to the individual files for details: alloc.c (always included) fer to the individual files for details: alloc.c (always included)
and setmode.c, strcasestr.c, strlfun.c and setmode.c, strlcpy.c

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/dot.mkshrc,v 1.6 2007/02/17 06:34:46 tg Exp $ # $MirOS: src/bin/mksh/dot.mkshrc,v 1.7 2007/03/04 03:04:23 tg Exp $
#- #-
# Add user-defined additions at the end, to prevent abortion on failure. # Add user-defined additions at the end, to prevent abortion on failure.
@ -17,8 +17,8 @@ PS1='$(((rv=$?)) && print $rv\|)${USER:=$(id -un)}@${HOSTNAME:=nil}:$(
fi fi
done done
print -r -- "$pfx$wd")'" $(if (( $(id -u) )); then print -r -- "$pfx$wd")'" $(if (( $(id -u) )); then
print \$; else print \#; fi) " MKSH=$(whence -p mksh) print \$; else print \#; fi) "
export EDITOR HOSTNAME MKSH PS1 USER export EDITOR HOSTNAME MKSH=$(whence -p mksh) PS1 USER
alias l='/bin/ls -F' alias l='/bin/ls -F'
alias la='l -a' alias la='l -a'
@ -32,9 +32,8 @@ alias lo='la -lo'
# any file(s) given as argument, or stdin if none, and spew to stdout # any file(s) given as argument, or stdin if none, and spew to stdout
function Lstripcom function Lstripcom
{ {
cat "$@" | while read _line; do cat "$@" | { set -o noglob; while read _line; do
set -o noglob
_line=${_line%%#*} _line=${_line%%#*}
[[ -n $_line ]] && print -r -- $_line [[ -n $_line ]] && print -r -- $_line
done done; }
} }

25
edit.c
View File

@ -5,7 +5,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.83 2007/03/04 00:13:14 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/edit.c,v 1.84 2007/03/04 03:04:24 tg Exp $");
/* tty driver characters we are interested in */ /* tty driver characters we are interested in */
typedef struct { typedef struct {
@ -36,7 +36,7 @@ int x_cf_glob(int, const char *, int, int, int *, int *, char ***, int *);
int x_longest_prefix(int, char *const *); int x_longest_prefix(int, char *const *);
int x_basename(const char *, const char *); int x_basename(const char *, const char *);
void x_free_words(int, char **); void x_free_words(int, char **);
int x_escape(const char *, size_t, int (*) (const char *, size_t)); int x_escape(const char *, size_t, int (*)(const char *, size_t));
int x_emacs(char *, size_t); int x_emacs(char *, size_t);
void x_init_emacs(void); void x_init_emacs(void);
int x_vi(char *, size_t); int x_vi(char *, size_t);
@ -133,9 +133,7 @@ x_getc(void)
runtraps(0); runtraps(0);
x_mode(true); x_mode(true);
} }
if (n != 1) return ((n == 1) ? (int)(unsigned char)c : -1);
return -1;
return (int)(unsigned char)c;
} }
void void
@ -484,7 +482,7 @@ x_locate_word(const char *buf, int buflen, int pos, int *startp,
for (p = start - 1; p >= 0 && ksh_isspace(buf[p]); for (p = start - 1; p >= 0 && ksh_isspace(buf[p]);
p--) p--)
; ;
iscmd = p < 0 || strchr(";|&()`", buf[p]); iscmd = p < 0 || vstrchr(";|&()`", buf[p]);
if (iscmd) { if (iscmd) {
/* If command has a /, path, etc. is not searched; /* If command has a /, path, etc. is not searched;
* only current directory is searched which is just * only current directory is searched which is just
@ -521,7 +519,7 @@ x_cf_glob(int flags, const char *buf, int buflen, int pos, int *startp,
if (len == 0 && is_command) if (len == 0 && is_command)
return 0; return 0;
nwords = (is_command ? x_command_glob : x_file_glob) (flags, nwords = (is_command ? x_command_glob : x_file_glob)(flags,
buf + *startp, len, &words); buf + *startp, len, &words);
if (nwords == 0) { if (nwords == 0) {
*wordsp = NULL; *wordsp = NULL;
@ -561,7 +559,7 @@ add_glob(const char *str, int slen)
if (*s == '\\' && s[1]) if (*s == '\\' && s[1])
s++; s++;
else if (*s == '*' || *s == '[' || *s == '?' || *s == '$' else if (*s == '*' || *s == '[' || *s == '?' || *s == '$'
|| (s[1] == '(' && strchr("*+?@!", *s))) || (s[1] == '(' && vstrchr("*+?@!", *s)))
break; break;
else if (*s == '/') else if (*s == '/')
saw_slash = true; saw_slash = true;
@ -602,7 +600,7 @@ x_free_words(int nwords, char **words)
int i; int i;
for (i = 0; i < nwords; i++) for (i = 0; i < nwords; i++)
afreechk(words[i]) afreechk(words[i]);
afree(words, ATEMP); afree(words, ATEMP);
} }
@ -672,7 +670,7 @@ glob_path(int flags, const char *pat, XPtrV *wp, const char *lpath)
Xinit(xs, xp, patlen + 128, ATEMP); Xinit(xs, xp, patlen + 128, ATEMP);
while (sp) { while (sp) {
xp = Xstring(xs, xp); xp = Xstring(xs, xp);
if (!(p = strchr(sp, ':'))) if (!(p = cstrchr(sp, ':')))
p = sp + strlen(sp); p = sp + strlen(sp);
pathlen = p - sp; pathlen = p - sp;
if (pathlen) { if (pathlen) {
@ -726,14 +724,15 @@ glob_path(int flags, const char *pat, XPtrV *wp, const char *lpath)
* keybinding-specific function * keybinding-specific function
*/ */
int int
x_escape(const char *s, size_t len, int (*putbuf_func) (const char *, size_t)) x_escape(const char *s, size_t len, int (*putbuf_func)(const char *, size_t))
{ {
size_t add, wlen; size_t add, wlen;
const char *ifs = str_val(local("IFS", 0)); const char *ifs = str_val(local("IFS", 0));
int rval = 0; int rval = 0;
for (add = 0, wlen = len; wlen - add > 0; add++) { for (add = 0, wlen = len; wlen - add > 0; add++) {
if (strchr("\\$()[{}*&;#|<>\"'`", s[add]) || strchr(ifs, s[add])) { if (vstrchr("\\$()[{}*&;#|<>\"'`", s[add]) ||
vstrchr(ifs, s[add])) {
if (putbuf_func(s, add) != 0) { if (putbuf_func(s, add) != 0) {
rval = -1; rval = -1;
break; break;
@ -3358,7 +3357,7 @@ static void ed_mov_opt(int, char *);
static int expand_word(int); static int expand_word(int);
static int complete_word(int, int); static int complete_word(int, int);
static int print_expansions(struct edstate *, int); static int print_expansions(struct edstate *, int);
#define char_len(c) ((c) < ' ' || (c) == 0x7F ? 2 : 1) #define char_len(c) ((c) < ' ' || (c) == 0x7F ? 2 : 1)
static void x_vi_zotc(int); static void x_vi_zotc(int);
static void vi_error(void); static void vi_error(void);
static void vi_macro_reset(void); static void vi_macro_reset(void);

21
eval.c
View File

@ -2,7 +2,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.23 2007/03/04 00:13:15 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.24 2007/03/04 03:04:24 tg Exp $");
#ifdef MKSH_SMALL #ifdef MKSH_SMALL
#define MKSH_NOPWNAM #define MKSH_NOPWNAM
@ -17,14 +17,14 @@ __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.23 2007/03/04 00:13:15 tg Exp $");
/* expansion generator state */ /* expansion generator state */
typedef struct Expand { typedef struct Expand {
/* int type; */ /* see expand() */ /* int type; */ /* see expand() */
const char *str; /* string */ const char *str; /* string */
union { union {
const char **strv;/* string[] */ const char **strv;/* string[] */
struct shf *shf;/* file */ struct shf *shf; /* file */
} u; /* source */ } u; /* source */
struct tbl *var; /* variable in ${var..} */ struct tbl *var; /* variable in ${var..} */
short split; /* split "$@" / call waitlast $() */ short split; /* split "$@" / call waitlast $() */
} Expand; } Expand;
#define XBASE 0 /* scanning original */ #define XBASE 0 /* scanning original */
@ -232,7 +232,7 @@ expand(const char *cp, /* input word */
type = comsub(&x, sp); type = comsub(&x, sp);
if (type == XCOM && (f&DOBLANK)) if (type == XCOM && (f&DOBLANK))
doblank++; doblank++;
sp = strchr(sp, 0) + 1; sp = cstrchr(sp, 0) + 1;
newlines = 0; newlines = 0;
} }
continue; continue;
@ -255,7 +255,7 @@ expand(const char *cp, /* input word */
v.name[0] = '\0'; v.name[0] = '\0';
v_evaluate(&v, substitute(sp, 0), v_evaluate(&v, substitute(sp, 0),
KSH_UNWIND_ERROR, true); KSH_UNWIND_ERROR, true);
sp = strchr(sp, 0) + 1; sp = cstrchr(sp, 0) + 1;
for (p = str_val(&v); *p; ) { for (p = str_val(&v); *p; ) {
Xcheck(ds, dp); Xcheck(ds, dp);
*dp++ = *p++; *dp++ = *p++;
@ -273,7 +273,7 @@ expand(const char *cp, /* input word */
int stype; int stype;
int slen = 0; int slen = 0;
sp = strchr(sp, '\0') + 1; /* skip variable */ sp = cstrchr(sp, '\0') + 1; /* skip variable */
type = varsub(&x, varname, sp, &stype, &slen); type = varsub(&x, varname, sp, &stype, &slen);
if (type < 0) { if (type < 0) {
char *beg, *end, *str; char *beg, *end, *str;
@ -1102,15 +1102,16 @@ globit(XString *xs, /* dest string */
char * char *
debunk(char *dp, const char *sp, size_t dlen) debunk(char *dp, const char *sp, size_t dlen)
{ {
char *d, *s; char *d;
const char *s;
if ((s = strchr(sp, MAGIC))) { if ((s = cstrchr(sp, MAGIC))) {
if (s - sp >= (ssize_t)dlen) if (s - sp >= (ssize_t)dlen)
return dp; return dp;
memcpy(dp, sp, s - sp); memcpy(dp, sp, s - sp);
for (d = dp + (s - sp); *s && (d - dp < (ssize_t)dlen); s++) for (d = dp + (s - sp); *s && (d - dp < (ssize_t)dlen); s++)
if (!ISMAGIC(*s) || !(*++s & 0x80) || if (!ISMAGIC(*s) || !(*++s & 0x80) ||
!strchr("*+?@! ", *s & 0x7f)) !vstrchr("*+?@! ", *s & 0x7f))
*d++ = *s; *d++ = *s;
else { else {
/* extended pattern operators: *+?@! */ /* extended pattern operators: *+?@! */

10
exec.c
View File

@ -2,7 +2,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.25 2007/03/04 00:13:15 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/exec.c,v 1.26 2007/03/04 03:04:24 tg Exp $");
static int comexec(struct op *, struct tbl *volatile, const char **, static int comexec(struct op *, struct tbl *volatile, const char **,
int volatile); int volatile);
@ -500,7 +500,7 @@ comexec(struct op *t, struct tbl *volatile tp, const char **ap,
rv = subst_exstat; rv = subst_exstat;
goto Leave; goto Leave;
} else if (!tp) { } else if (!tp) {
if (Flag(FRESTRICTED) && strchr(cp, '/')) { if (Flag(FRESTRICTED) && vstrchr(cp, '/')) {
warningf(true, "%s: restricted", cp); warningf(true, "%s: restricted", cp);
rv = 1; rv = 1;
goto Leave; goto Leave;
@ -814,7 +814,7 @@ findcom(const char *name, int flags)
char *fpath; /* for function autoloading */ char *fpath; /* for function autoloading */
const char *npath; const char *npath;
if (strchr(name, '/') != NULL) { if (vstrchr(name, '/')) {
insert = 0; insert = 0;
/* prevent FPATH search below */ /* prevent FPATH search below */
flags &= ~FC_FUNC; flags &= ~FC_FUNC;
@ -946,7 +946,7 @@ search(const char *name, const char *lpath,
if (errnop) if (errnop)
*errnop = 0; *errnop = 0;
if (strchr(name, '/')) { if (vstrchr(name, '/')) {
if (search_access(name, mode, errnop) == 0) if (search_access(name, mode, errnop) == 0)
return (name); return (name);
return NULL; return NULL;
@ -958,7 +958,7 @@ search(const char *name, const char *lpath,
sp = lpath; sp = lpath;
while (sp != NULL) { while (sp != NULL) {
xp = Xstring(xs, xp); xp = Xstring(xs, xp);
if (!(p = strchr(sp, ':'))) if (!(p = cstrchr(sp, ':')))
p = sp + strlen(sp); p = sp + strlen(sp);
if (p != sp) { if (p != sp) {
XcheckN(xs, xp, p - sp); XcheckN(xs, xp, p - sp);

35
expr.c
View File

@ -2,7 +2,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.9 2007/03/03 21:12:51 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/expr.c,v 1.10 2007/03/04 03:04:25 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 {
@ -102,17 +102,16 @@ static const struct opinfo opinfo[] = {
{ "(", 1, P_PRIMARY }, { "(", 1, P_PRIMARY },
{ ")", 1, P_PRIMARY }, { ")", 1, P_PRIMARY },
{ ":", 1, P_PRIMARY }, { ":", 1, P_PRIMARY },
{ "", 0, P_PRIMARY } /* end of table */ { "", 0, P_PRIMARY }
}; };
typedef struct expr_state Expr_state; typedef struct expr_state Expr_state;
struct expr_state { struct expr_state {
const char *expression; /* expression being evaluated */ const char *expression; /* expression being evaluated */
const char *tokp; /* lexical position */ const char *tokp; /* lexical position */
enum token tok; /* token from token() */ enum token tok; /* token from token() */
int noassign; /* don't do assigns (for ?:,&&,||) */ int noassign; /* don't do assigns (for ?:,&&,||) */
bool arith; /* true if evaluating an $(()) bool arith; /* true if evaluating an $(())
* expression * expression
*/ */
struct tbl *val; /* value from token() */ struct tbl *val; /* value from token() */
@ -129,9 +128,9 @@ enum error_type {
static void evalerr(Expr_state *, enum error_type, const char *) static void evalerr(Expr_state *, enum error_type, const char *)
__attribute__((noreturn)); __attribute__((noreturn));
static struct tbl *evalexpr(Expr_state *, enum prec); static struct tbl *evalexpr(Expr_state *, enum prec);
static void exprtoken(Expr_state *); static void exprtoken(Expr_state *);
static struct tbl *do_ppmm(Expr_state *, enum token, struct tbl *, bool); static struct tbl *do_ppmm(Expr_state *, enum token, struct tbl *, bool);
static void assign_check(Expr_state *, enum token, struct tbl *); static void assign_check(Expr_state *, enum token, struct tbl *);
static struct tbl *tempvar(void); static struct tbl *tempvar(void);
static struct tbl *intvar(Expr_state *, struct tbl *); static struct tbl *intvar(Expr_state *, struct tbl *);
@ -148,7 +147,7 @@ evaluate(const char *expr, long int *rval, int error_ok, bool arith)
v.type = 0; v.type = 0;
ret = v_evaluate(&v, expr, error_ok, arith); ret = v_evaluate(&v, expr, error_ok, arith);
*rval = v.val.i; *rval = v.val.i;
return ret; return (ret);
} }
/* /*
@ -178,7 +177,7 @@ v_evaluate(struct tbl *vp, const char *expr, volatile int error_ok,
quitenv(NULL); quitenv(NULL);
if (i == LAEXPR) { if (i == LAEXPR) {
if (error_ok == KSH_RETURN_ERROR) if (error_ok == KSH_RETURN_ERROR)
return 0; return (0);
errorf(null); errorf(null);
} }
unwind(i); unwind(i);
@ -203,7 +202,7 @@ v_evaluate(struct tbl *vp, const char *expr, volatile int error_ok,
quitenv(NULL); quitenv(NULL);
return 1; return (1);
} }
static void static void
@ -304,7 +303,7 @@ evalexpr(Expr_state *es, enum prec prec)
vl = do_ppmm(es, es->tok, vl, false); vl = do_ppmm(es, es->tok, vl, false);
exprtoken(es); exprtoken(es);
} }
return vl; return (vl);
} }
vl = evalexpr(es, ((int) prec) - 1); vl = evalexpr(es, ((int) prec) - 1);
for (op = es->tok; IS_BINOP(op) && opinfo[(int) op].prec == prec; for (op = es->tok; IS_BINOP(op) && opinfo[(int) op].prec == prec;
@ -437,7 +436,7 @@ evalexpr(Expr_state *es, enum prec prec)
} else if (op != O_TERN) } else if (op != O_TERN)
vl->val.i = res; vl->val.i = res;
} }
return vl; return (vl);
} }
static void static void
@ -526,7 +525,7 @@ do_ppmm(Expr_state *es, enum token op, struct tbl *vasn, bool is_prefix)
if (!is_prefix) /* undo the inc/dec */ if (!is_prefix) /* undo the inc/dec */
vl->val.i = oval; vl->val.i = oval;
return vl; return (vl);
} }
static void static void
@ -543,13 +542,13 @@ tempvar(void)
{ {
struct tbl *vp; struct tbl *vp;
vp = (struct tbl*) alloc(sizeof(struct tbl), ATEMP); vp = (struct tbl *)alloc(sizeof (struct tbl), ATEMP);
vp->flag = ISSET|INTEGER; vp->flag = ISSET|INTEGER;
vp->type = 0; vp->type = 0;
vp->areap = ATEMP; vp->areap = ATEMP;
vp->val.i = 0; vp->val.i = 0;
vp->name[0] = '\0'; vp->name[0] = '\0';
return vp; return (vp);
} }
/* cast (string) variable to temporary integer variable */ /* cast (string) variable to temporary integer variable */
@ -561,7 +560,7 @@ intvar(Expr_state *es, struct tbl *vp)
/* try to avoid replacing a temp var with another temp var */ /* try to avoid replacing a temp var with another temp var */
if (vp->name[0] == '\0' && if (vp->name[0] == '\0' &&
(vp->flag & (ISSET|INTEGER|EXPRLVALUE)) == (ISSET|INTEGER)) (vp->flag & (ISSET|INTEGER|EXPRLVALUE)) == (ISSET|INTEGER))
return vp; return (vp);
vq = tempvar(); vq = tempvar();
if (setint_v(vq, vp, es->arith) == NULL) { if (setint_v(vq, vp, es->arith) == NULL) {
@ -573,5 +572,5 @@ intvar(Expr_state *es, struct tbl *vp)
vp->flag &= ~EXPRINEVAL; vp->flag &= ~EXPRINEVAL;
es->evaling = NULL; es->evaling = NULL;
} }
return vq; return (vq);
} }

31
funcs.c
View File

@ -5,7 +5,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.47 2007/03/04 00:13:15 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.48 2007/03/04 03:04:25 tg Exp $");
int int
c_cd(const char **wp) c_cd(const char **wp)
@ -53,7 +53,7 @@ c_cd(const char **wp)
} else if (!wp[1]) { } else if (!wp[1]) {
/* One argument: - or dir */ /* One argument: - or dir */
dir = str_save(wp[0], ATEMP); dir = str_save(wp[0], ATEMP);
if (strcmp(dir, "-") == 0) { if (ksh_isdash(dir)) {
afree(dir, ATEMP); afree(dir, ATEMP);
dir = str_val(oldpwd_s); dir = str_val(oldpwd_s);
if (dir == null) { if (dir == null) {
@ -280,7 +280,7 @@ c_print(const char **wp)
if (!(builtin_opt.info & GI_MINUSMINUS)) { if (!(builtin_opt.info & GI_MINUSMINUS)) {
/* treat a lone - like -- */ /* treat a lone - like -- */
if (wp[builtin_opt.optind] && if (wp[builtin_opt.optind] &&
strcmp(wp[builtin_opt.optind], "-") == 0) ksh_isdash(wp[builtin_opt.optind]))
builtin_opt.optind++; builtin_opt.optind++;
} else if (flags & PO_PMINUSMINUS) } else if (flags & PO_PMINUSMINUS)
builtin_opt.optind--; builtin_opt.optind--;
@ -1314,7 +1314,8 @@ int
c_bind(const char **wp) c_bind(const char **wp)
{ {
int optc, rv = 0, macro = 0, list = 0; int optc, rv = 0, macro = 0, list = 0;
char *cp; const char *cp;
char *up;
while ((optc = ksh_getopt(wp, &builtin_opt, "lm")) != -1) while ((optc = ksh_getopt(wp, &builtin_opt, "lm")) != -1)
switch (optc) { switch (optc) {
@ -1333,11 +1334,15 @@ c_bind(const char **wp)
rv = x_bind((char*)NULL, (char*)NULL, 0, list); rv = x_bind((char*)NULL, (char*)NULL, 0, list);
for (; *wp != NULL; wp++) { for (; *wp != NULL; wp++) {
cp = strchr(*wp, '='); if ((cp = cstrchr(*wp, '=')) == NULL)
if (cp != NULL) up = NULL;
*cp++ = '\0'; else {
if (x_bind(*wp, cp, macro, 0)) up = str_save(*wp, ATEMP);
up[cp++ - *wp] = '\0';
}
if (x_bind(up ? up : *wp, cp, macro, 0))
rv = 1; rv = 1;
afreechk(up);
} }
return rv; return rv;
@ -1472,7 +1477,7 @@ c_umask(const char **wp)
new_umask = old_umask; new_umask = old_umask;
positions = 0; positions = 0;
while (*cp) { while (*cp) {
while (*cp && strchr("augo", *cp)) while (*cp && vstrchr("augo", *cp))
switch (*cp++) { switch (*cp++) {
case 'a': case 'a':
positions |= 0111; positions |= 0111;
@ -1489,11 +1494,11 @@ c_umask(const char **wp)
} }
if (!positions) if (!positions)
positions = 0111; /* default is a */ positions = 0111; /* default is a */
if (!strchr("=+-", op = *cp)) if (!vstrchr("=+-", op = *cp))
break; break;
cp++; cp++;
new_val = 0; new_val = 0;
while (*cp && strchr("rwxugoXs", *cp)) while (*cp && vstrchr("rwxugoXs", *cp))
switch (*cp++) { switch (*cp++) {
case 'r': new_val |= 04; break; case 'r': new_val |= 04; break;
case 'w': new_val |= 02; break; case 'w': new_val |= 02; break;
@ -1525,7 +1530,7 @@ c_umask(const char **wp)
if (*cp == ',') { if (*cp == ',') {
positions = 0; positions = 0;
cp++; cp++;
} else if (!strchr("=+-", *cp)) } else if (!vstrchr("=+-", *cp))
break; break;
} }
if (*cp) { if (*cp) {
@ -2033,7 +2038,7 @@ c_unset(const char **wp)
bi_errorf("%s is read only", vp->name); bi_errorf("%s is read only", vp->name);
return 1; return 1;
} }
unset(vp, strchr(id, '[') ? 1 : 0); unset(vp, vstrchr(id, '[') ? 1 : 0);
} else { /* unset function */ } else { /* unset function */
if (define(id, (struct op *) NULL)) if (define(id, (struct op *) NULL))
ret = 1; ret = 1;

View File

@ -3,7 +3,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.44 2007/03/04 00:13:16 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.45 2007/03/04 03:04:25 tg Exp $");
Trap sigtraps[NSIG + 1]; Trap sigtraps[NSIG + 1];
static struct sigaction Sigact_ign, Sigact_trap; static struct sigaction Sigact_ign, Sigact_trap;
@ -18,20 +18,20 @@ static void writehistfile(int, char *);
static int sprinkle(int); static int sprinkle(int);
#endif #endif
static int hist_execute(char *); static int hist_execute(char *);
static int hist_replace(char **, const char *, const char *, int); static int hist_replace(char **, const char *, const char *, int);
static char **hist_get(const char *, int, int); static char **hist_get(const char *, int, int);
static char **hist_get_oldest(void); static char **hist_get_oldest(void);
static void histbackup(void); static void histbackup(void);
static char **current; /* current position in history[] */ static char **current; /* current position in history[] */
static int hstarted; /* set after hist_init() called */ static int hstarted; /* set after hist_init() called */
static Source *hist_source; static Source *hist_source;
#if HAVE_PERSISTENT_HISTORY #if HAVE_PERSISTENT_HISTORY
static char *hname; /* current name of history file */ static char *hname; /* current name of history file */
static int histfd; static int histfd;
static int hsize; static int hsize;
#endif #endif
int int
@ -56,7 +56,7 @@ c_fc(const char **wp)
switch (optc) { switch (optc) {
case 'e': case 'e':
p = builtin_opt.optarg; p = builtin_opt.optarg;
if (strcmp(p, "-") == 0) if (ksh_isdash(p))
sflag++; sflag++;
else { else {
size_t len = strlen(p); size_t len = strlen(p);

49
jobs.c
View File

@ -2,7 +2,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.18 2007/01/12 10:18:21 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.19 2007/03/04 03:04:25 tg Exp $");
/* Order important! */ /* Order important! */
#define PRUNNING 0 #define PRUNNING 0
@ -12,11 +12,11 @@ __RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.18 2007/01/12 10:18:21 tg Exp $");
typedef struct proc Proc; typedef struct proc Proc;
struct proc { struct proc {
Proc *next; /* next process in pipeline (if any) */ Proc *next; /* next process in pipeline (if any) */
int state; int state;
int status; /* wait status */ int status; /* wait status */
pid_t pid; /* process id */ pid_t pid; /* process id */
char command[48]; /* process command string */ char command[48]; /* process command string */
}; };
/* Notify/print flag - j_print() argument */ /* Notify/print flag - j_print() argument */
@ -46,21 +46,21 @@ struct proc {
typedef struct job Job; typedef struct job Job;
struct job { struct job {
Job *next; /* next job in list */ Job *next; /* next job in list */
int job; /* job number: %n */ int job; /* job number: %n */
int flags; /* see JF_* */ int flags; /* see JF_* */
int state; /* job state */ int state; /* job state */
int status; /* exit status of last process */ int status; /* exit status of last process */
pid_t pgrp; /* process group of job */ pid_t pgrp; /* process group of job */
pid_t ppid; /* pid of process that forked job */ pid_t ppid; /* pid of process that forked job */
int32_t age; /* number of jobs started */ int32_t age; /* number of jobs started */
struct timeval systime; /* system time used by job */ struct timeval systime; /* system time used by job */
struct timeval usrtime; /* user time used by job */ struct timeval usrtime; /* user time used by job */
Proc *proc_list; /* process list */ Proc *proc_list; /* process list */
Proc *last_proc; /* last process in list */ Proc *last_proc; /* last process in list */
Coproc_id coproc_id; /* 0 or id of coprocess output pipe */ Coproc_id coproc_id; /* 0 or id of coprocess output pipe */
struct termios ttystate;/* saved tty state for stopped jobs */ struct termios ttystate;/* saved tty state for stopped jobs */
pid_t saved_ttypgrp; /* saved tty process group for stopped jobs */ pid_t saved_ttypgrp; /* saved tty process group for stopped jobs */
}; };
/* Flags for j_waitj() */ /* Flags for j_waitj() */
@ -75,7 +75,7 @@ struct job {
#define JL_AMBIG 2 /* %foo or %?foo is ambiguous */ #define JL_AMBIG 2 /* %foo or %?foo is ambiguous */
#define JL_INVALID 3 /* non-pid, non-% job id */ #define JL_INVALID 3 /* non-pid, non-% job id */
static const char *const lookup_msgs[] = { static const char *const lookup_msgs[] = {
null, null,
"no such job", "no such job",
"ambiguous", "ambiguous",
@ -83,15 +83,16 @@ static const char *const lookup_msgs[] = {
NULL NULL
}; };
struct timeval j_systime, j_usrtime; /* user and system time of last j_waitjed job */ /* user and system time of last j_waitjed job */
struct timeval j_systime, j_usrtime;
static Job *job_list; /* job list */ static Job *job_list; /* job list */
static Job *last_job; static Job *last_job;
static Job *async_job; static Job *async_job;
static pid_t async_pid; static pid_t async_pid;
static int nzombie; /* # of zombies owned by this process */ static int nzombie; /* # of zombies owned by this process */
static int32_t njobs; /* # of jobs started */ static int32_t njobs; /* # of jobs started */
#ifndef CHILD_MAX #ifndef CHILD_MAX
#define CHILD_MAX _POSIX_CHILD_MAX #define CHILD_MAX _POSIX_CHILD_MAX

11
lex.c
View File

@ -2,7 +2,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.25 2007/01/12 10:18:21 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/lex.c,v 1.26 2007/03/04 03:04:26 tg Exp $");
/* Structure to keep track of the lexing state and the various pieces of info /* Structure to keep track of the lexing state and the various pieces of info
* needed for each particular state. */ * needed for each particular state. */
@ -42,11 +42,10 @@ struct lex_state {
typedef struct State_info State_info; typedef struct State_info State_info;
struct State_info { struct State_info {
Lex_state *base; Lex_state *base;
Lex_state *end; Lex_state *end;
}; };
static void readhere(struct ioword *); static void readhere(struct ioword *);
static int getsc__(void); static int getsc__(void);
static void getsc_line(Source *); static void getsc_line(Source *);
@ -83,10 +82,8 @@ static int ignore_backslash_newline;
state = statep->ls_state; \ state = statep->ls_state; \
} while (0) } while (0)
/* /*
* Lexical analyzer * Lexical analyser
* *
* tokens are not regular expressions, they are LL(1). * tokens are not regular expressions, they are LL(1).
* for example, "${var:-${PWD}}", and "$(size $(whence ksh))". * for example, "${var:-${PWD}}", and "$(size $(whence ksh))".

4
main.c
View File

@ -13,7 +13,7 @@
#include <locale.h> #include <locale.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.72 2007/03/04 00:13:16 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/main.c,v 1.73 2007/03/04 03:04:26 tg Exp $");
extern char **environ; extern char **environ;
@ -292,7 +292,7 @@ main(int argc, const char *argv[])
#ifndef MKSH_ASSUME_UTF8 #ifndef MKSH_ASSUME_UTF8
#if HAVE_SETLOCALE_CTYPE #if HAVE_SETLOCALE_CTYPE
#define isuc(x) (((x) != NULL) && \ #define isuc(x) (((x) != NULL) && \
(strcasestr((x), "UTF-8") || strcasestr((x), "utf8"))) (stristr((x), "UTF-8") || stristr((x), "utf8")))
/* Check if we're in a UTF-8 locale */ /* Check if we're in a UTF-8 locale */
if (!Flag(FUTFHACK)) { if (!Flag(FUTFHACK)) {
cc = setlocale(LC_CTYPE, ""); cc = setlocale(LC_CTYPE, "");

89
misc.c
View File

@ -6,7 +6,7 @@
#include <grp.h> #include <grp.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.51 2007/03/04 00:13:16 tg Exp $\t" __RCSID("$MirOS: src/bin/mksh/misc.c,v 1.52 2007/03/04 03:04:26 tg Exp $\t"
MKSH_SH_H_ID); MKSH_SH_H_ID);
#undef USE_CHVT #undef USE_CHVT
@ -311,12 +311,15 @@ parse_args(const char **argv,
} }
if (what == OF_CMDLINE) { if (what == OF_CMDLINE) {
char *p; const char *p = argv[0], *q;
/* Set FLOGIN before parsing options so user can clear /* Set FLOGIN before parsing options so user can clear
* flag using +l. * flag using +l.
*/ */
Flag(FLOGIN) = (argv[0][0] == '-' || if (*p != '-')
((p = strrchr(argv[0], '/')) && *++p == '-')); for (q = p; *q; )
if (*q++ == '/')
p = q;
Flag(FLOGIN) = (*p == '-');
opts = cmd_opts; opts = cmd_opts;
} else if (what == OF_FIRSTTIME) { } else if (what == OF_FIRSTTIME) {
opts = cmd_opts; opts = cmd_opts;
@ -558,7 +561,7 @@ has_globbing(const char *xp, const char *xpe)
return 0; return 0;
in_bracket = 0; in_bracket = 0;
} }
} else if ((c & 0x80) && strchr("*+?@! ", c & 0x7f)) { } else if ((c & 0x80) && vstrchr("*+?@! ", c & 0x7f)) {
saw_glob = 1; saw_glob = 1;
if (in_bracket) if (in_bracket)
bnest++; bnest++;
@ -758,7 +761,7 @@ pat_scan(const unsigned char *p, const unsigned char *pe, int match_sep)
if ((*++p == /*(*/ ')' && nest-- == 0) || if ((*++p == /*(*/ ')' && nest-- == 0) ||
(*p == '|' && match_sep && nest == 0)) (*p == '|' && match_sep && nest == 0))
return ++p; return ++p;
if ((*p & 0x80) && strchr("*+?@! ", *p & 0x7f)) if ((*p & 0x80) && vstrchr("*+?@! ", *p & 0x7f))
nest++; nest++;
} }
return NULL; return NULL;
@ -811,7 +814,7 @@ int
ksh_getopt(const char **argv, Getopt *go, const char *optionsp) ksh_getopt(const char **argv, Getopt *go, const char *optionsp)
{ {
char c; char c;
char *o; const char *o;
if (go->p == 0 || (c = argv[go->optind - 1][go->p]) == '\0') { if (go->p == 0 || (c = argv[go->optind - 1][go->p]) == '\0') {
const char *arg = argv[go->optind], flag = arg ? *arg : '\0'; const char *arg = argv[go->optind], flag = arg ? *arg : '\0';
@ -836,7 +839,7 @@ ksh_getopt(const char **argv, Getopt *go, const char *optionsp)
} }
go->p++; go->p++;
if (c == '?' || c == ':' || c == ';' || c == ',' || c == '#' || if (c == '?' || c == ':' || c == ';' || c == ',' || c == '#' ||
!(o = strchr(optionsp, c))) { !(o = cstrchr(optionsp, c))) {
if (optionsp[0] == ':') { if (optionsp[0] == ':') {
go->buf[0] = c; go->buf[0] = c;
go->optarg = go->buf; go->optarg = go->buf;
@ -921,18 +924,18 @@ print_value_quoted(const char *s)
} }
for (p = s; *p; p++) { for (p = s; *p; p++) {
if (*p == '\'') { if (*p == '\'') {
shprintf("'\\'" + 1 - inquote); if (inquote)
shf_putc('\'', shl_stdout);
shf_putc('\\', shl_stdout);
inquote = 0; inquote = 0;
} else { } else if (!inquote) {
if (!inquote) { shf_putc('\'', shl_stdout);
shprintf("'"); inquote = 1;
inquote = 1;
}
shf_putc(*p, shl_stdout);
} }
shf_putc(*p, shl_stdout);
} }
if (inquote) if (inquote)
shprintf("'"); shf_putc('\'', shl_stdout);
} }
/* Print things in columns and rows - func() is called to format the ith /* Print things in columns and rows - func() is called to format the ith
@ -1281,7 +1284,7 @@ do_phys_path(XString *xsp, char *xp, const char *pathl)
p++; p++;
if (!*p) if (!*p)
break; break;
len = (q = strchr(p, '/')) ? q - p : (int)strlen(p); len = (q = cstrchr(p, '/')) ? q - p : (int)strlen(p);
if (len == 1 && p[0] == '.') if (len == 1 && p[0] == '.')
continue; continue;
if (len == 2 && p[0] == '.' && p[1] == '.') { if (len == 2 && p[0] == '.' && p[1] == '.') {
@ -1372,3 +1375,55 @@ chvt(const char *fn)
close(fd); close(fd);
} }
#endif #endif
#ifdef DEBUG
char *
strchr(char *p, int ch)
{
for (;; ++p) {
if (*p == ch)
return (p);
if (!*p)
return (NULL);
}
/* NOTREACHED */
}
char *
strstr(char *b, const char *l)
{
char first, c;
size_t n;
if ((first = *l++) == '\0')
return (b);
n = strlen(l);
strstr_look:
while ((c = *b++) != first)
if (c == '\0')
return (NULL);
if (strncmp(b, l, n))
goto strstr_look;
return (b - 1);
}
#endif
#if !HAVE_STRCASESTR
const char *
stristr(const char *b, const char *l)
{
char first, c;
size_t n;
if ((first = *l++), ((first = ksh_tolower(first)) == '\0'))
return (b);
n = strlen(l);
stristr_look:
while ((c = *b++), ((c = ksh_tolower(c)) != first))
if (c == '\0')
return (NULL);
if (strncasecmp(b, l, n))
goto stristr_look;
return (b - 1);
}
#endif

8
mksh.1
View File

@ -1,7 +1,7 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.78 2007/01/18 16:23:52 tg Exp $ .\" $MirOS: src/bin/mksh/mksh.1,v 1.79 2007/03/04 03:04:26 tg Exp $
.\" $OpenBSD: ksh.1,v 1.118 2006/11/30 08:47:58 jmc Exp $ .\" $OpenBSD: ksh.1,v 1.118 2006/11/30 08:47:58 jmc Exp $
.\" .\"
.Dd January 18, 2007 .Dd March 4, 2007
.Dt MKSH 1 .Dt MKSH 1
.Os MirBSD .Os MirBSD
.Sh NAME .Sh NAME
@ -5293,7 +5293,7 @@ Please report bugs in
to the to the
.Aq miros-discuss@mirbsd.org .Aq miros-discuss@mirbsd.org
mailing list or in the mailing list or in the
.Li \&#\&!/bin/mksh Pq \&#mksh .Li \&#\&!/bin/mksh
or or
.Li \&#ksh .Li \&#ksh
IRC channel at IRC channel at
@ -5309,4 +5309,4 @@ is executed in a subshell.
This is an This is an
.Nm .Nm
feature which can be depended on by scripts. feature which can be depended on by scripts.
Use co-routines to work around if necessary and possible. Use co-processes to work around if necessary and possible.

147
sh.h
View File

@ -8,14 +8,14 @@
/* $OpenBSD: c_test.h,v 1.4 2004/12/20 11:34:26 otto Exp $ */ /* $OpenBSD: c_test.h,v 1.4 2004/12/20 11:34:26 otto Exp $ */
/* $OpenBSD: tty.h,v 1.5 2004/12/20 11:34:26 otto Exp $ */ /* $OpenBSD: tty.h,v 1.5 2004/12/20 11:34:26 otto Exp $ */
#define MKSH_SH_H_ID "$MirOS: src/bin/mksh/sh.h,v 1.114 2007/03/04 00:13:16 tg Exp $" #define MKSH_SH_H_ID "$MirOS: src/bin/mksh/sh.h,v 1.115 2007/03/04 03:04:27 tg Exp $"
#define MKSH_VERSION "R29 2007/02/16" #define MKSH_VERSION "R29 2007/03/04"
#if HAVE_SYS_PARAM_H #if HAVE_SYS_PARAM_H
#include <sys/param.h> #include <sys/param.h>
#endif #endif
#include <sys/types.h> #include <sys/types.h>
#if defined(HAVE_MULTI_IDSTRING) && !HAVE_MULTI_IDSTRING #if !HAVE_MULTI_IDSTRING
#undef __RCSID #undef __RCSID
#endif #endif
#if !defined(__RCSID) || !defined(__SCCSID) #if !defined(__RCSID) || !defined(__SCCSID)
@ -129,6 +129,7 @@ typedef int bool;
#define ksh_isupper(c) (((c) >= 'A') && ((c) <= 'Z')) #define ksh_isupper(c) (((c) >= 'A') && ((c) <= 'Z'))
#define ksh_tolower(c) (((c) >= 'A') && ((c) <= 'Z') ? (c) - 'A' + 'a' : (c)) #define ksh_tolower(c) (((c) >= 'A') && ((c) <= 'Z') ? (c) - 'A' + 'a' : (c))
#define ksh_toupper(c) (((c) >= 'a') && ((c) <= 'z') ? (c) - 'a' + 'A' : (c)) #define ksh_toupper(c) (((c) >= 'a') && ((c) <= 'z') ? (c) - 'a' + 'A' : (c))
#define ksh_isdash(s) (((s) != NULL) && ((s)[0] == '-') && ((s)[1] == '\0'))
#if HAVE_ATTRIBUTE #if HAVE_ATTRIBUTE
#undef __attribute__ #undef __attribute__
@ -151,18 +152,18 @@ typedef int bool;
}) })
#ifndef S_ISTXT #ifndef S_ISTXT
#define S_ISTXT 0001000 #define S_ISTXT 0001000
#endif #endif
#ifndef DEFFILEMODE #ifndef DEFFILEMODE
#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) #define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
#endif #endif
#if !defined(RLIMIT_VMEM) && defined(RLIMIT_AS) #if !defined(RLIMIT_VMEM) && defined(RLIMIT_AS)
#define RLIMIT_VMEM RLIMIT_AS #define RLIMIT_VMEM RLIMIT_AS
#endif #endif
#if !defined(MAP_FAILED) && defined(__linux) #if !defined(MAP_FAILED) && defined(__linux)
#define MAP_FAILED ((void *)-1) #define MAP_FAILED ((void *)-1)
#endif #endif
/* OS-dependent additions */ /* OS-dependent additions */
@ -172,7 +173,7 @@ mode_t getmode(const void *, mode_t);
void *setmode(const char *); void *setmode(const char *);
#endif #endif
#if !HAVE_STRCASESTR #if !HAVE_STRCASESTR
char *strcasestr(const char *, const char *); const char *stristr(const char *, const char *);
#endif #endif
#if !HAVE_STRLCPY #if !HAVE_STRLCPY
size_t strlcpy(char *, const char *, size_t); size_t strlcpy(char *, const char *, size_t);
@ -220,15 +221,15 @@ typedef int32_t Tflag;
#define PATH_MAX 1024 /* pathname size */ #define PATH_MAX 1024 /* pathname size */
#endif #endif
EXTERN const char *kshname; /* $0 */ EXTERN const char *kshname; /* $0 */
EXTERN pid_t kshpid; /* $$, shell pid */ EXTERN pid_t kshpid; /* $$, shell pid */
EXTERN pid_t procpid; /* pid of executing process */ EXTERN pid_t procpid; /* pid of executing process */
EXTERN uid_t ksheuid; /* effective uid of shell */ EXTERN uid_t ksheuid; /* effective uid of shell */
EXTERN int exstat; /* exit status */ EXTERN int exstat; /* exit status */
EXTERN int subst_exstat; /* exit status of last $(..)/`..` */ EXTERN int subst_exstat; /* exit status of last $(..)/`..` */
EXTERN const char *safe_prompt; /* safe prompt if PS1 substitution fails */ EXTERN const char *safe_prompt; /* safe prompt if PS1 substitution fails */
EXTERN const char initvsn[] I__("KSH_VERSION=@(#)MIRBSD KSH " MKSH_VERSION); EXTERN const char initvsn[] I__("KSH_VERSION=@(#)MIRBSD KSH " MKSH_VERSION);
#define KSH_VERSION (initvsn + 16) #define KSH_VERSION (initvsn + /* "KSH_VERSION=@(#)" */ 16)
/* /*
* Evil hack for const correctness due to API brokenness * Evil hack for const correctness due to API brokenness
@ -241,6 +242,13 @@ union mksh_ccphack {
char **rw; char **rw;
const char **ro; const char **ro;
}; };
/* for const debugging */
#ifdef DEBUG
char *ucstrchr(char *, int);
char *ucstrstr(char *, const char *);
#define strchr ucstrchr
#define strstr ucstrstr
#define cstrchr(s,c) __extension__({ \ #define cstrchr(s,c) __extension__({ \
union mksh_cchack in, out; \ union mksh_cchack in, out; \
\ \
@ -248,6 +256,42 @@ union mksh_ccphack {
out.rw = strchr(in.rw, (c)); \ out.rw = strchr(in.rw, (c)); \
(out.ro); \ (out.ro); \
}) })
#define cstrstr(b,l) __extension__({ \
union mksh_cchack in, out; \
\
in.ro = (b); \
out.rw = strstr(in.rw, (l)); \
(out.ro); \
})
#define vstrchr(s,c) (cstrchr((s), (c)) != NULL)
#define vstrstr(b,l) (cstrstr((b), (l)) != NULL)
#if HAVE_STRCASESTR
#define stristr(b,l) __extension__({ \
union mksh_cchack out; \
\
out.rw = strcasestr((b), (l)); \
(out.ro); \
})
#endif
#else
#define cstrchr(s,c) __extension__({ \
union mksh_cchack out; \
\
out.rw = strchr((s), (c)); \
(out.ro); \
})
#define cstrstr(b,l) __extension__({ \
union mksh_cchack out; \
\
out.rw = strstr((b), (l)); \
(out.ro); \
})
#define vstrchr strchr
#define vstrstr strstr
#if HAVE_STRCASESTR
#define stristr strcasestr
#endif
#endif
/* /*
* Area-based allocation built on malloc/free * Area-based allocation built on malloc/free
@ -364,11 +408,11 @@ enum sh_flag {
#define Flag(f) (shell_flags[(int) (f)]) #define Flag(f) (shell_flags[(int) (f)])
EXTERN char shell_flags [FNFLAGS]; EXTERN char shell_flags [FNFLAGS];
EXTERN char null [] I__(""); /* null value for variable */ EXTERN char null [] I__(""); /* null value for variable */
EXTERN char space [] I__(" "); EXTERN char space [] I__(" ");
EXTERN char newline [] I__("\n"); EXTERN char newline [] I__("\n");
enum temp_type { enum temp_type {
TT_HEREDOC_EXP, /* expanded heredoc */ TT_HEREDOC_EXP, /* expanded heredoc */
@ -432,9 +476,9 @@ typedef struct trap {
#define SIGEXIT_ 0 /* for trap EXIT */ #define SIGEXIT_ 0 /* for trap EXIT */
#define SIGERR_ NSIG /* for trap ERR */ #define SIGERR_ NSIG /* for trap ERR */
EXTERN volatile sig_atomic_t trap; /* traps pending? */ EXTERN volatile sig_atomic_t trap; /* traps pending? */
EXTERN volatile sig_atomic_t intrsig; /* pending trap interrupts command */ EXTERN volatile sig_atomic_t intrsig; /* pending trap interrupts command */
EXTERN volatile sig_atomic_t fatal_trap;/* received a fatal signal */ EXTERN volatile sig_atomic_t fatal_trap;/* received a fatal signal */
extern Trap sigtraps[NSIG+1]; extern Trap sigtraps[NSIG+1];
/* /*
@ -442,7 +486,7 @@ extern Trap sigtraps[NSIG+1];
*/ */
/* values for ksh_tmout_state */ /* values for ksh_tmout_state */
enum tmout_enum { enum tmout_enum {
TMOUT_EXECUTING = 0, /* executing commands */ TMOUT_EXECUTING = 0, /* executing commands */
TMOUT_READING, /* waiting for input */ TMOUT_READING, /* waiting for input */
TMOUT_LEAVING /* have timed out */ TMOUT_LEAVING /* have timed out */
}; };
@ -531,7 +575,7 @@ EXTERN size_t current_wd_size;
/* Minimum allowed value for x_cols: 2 for prompt, 3 for " < " at end of line /* Minimum allowed value for x_cols: 2 for prompt, 3 for " < " at end of line
*/ */
#define MIN_COLS (2 + MIN_EDIT_SPACE + 3) #define MIN_COLS (2 + MIN_EDIT_SPACE + 3)
EXTERN int x_cols I__(80); /* tty columns */ EXTERN int x_cols I__(80); /* tty columns */
/* These to avoid bracket matching problems */ /* These to avoid bracket matching problems */
#define OPAREN '(' #define OPAREN '('
@ -621,10 +665,10 @@ struct tbl { /* table item */
* or offset from val.s of value (if EXPORT) */ * or offset from val.s of value (if EXPORT) */
Area *areap; /* area to allocate from */ Area *areap; /* area to allocate from */
union { union {
char *s; /* string */ char *s; /* string */
long i; /* integer */ long i; /* integer */
int (*f)(const char **); /* int function */ int (*f)(const char **);/* int function */
struct op *t; /* "function" tree */ struct op *t; /* "function" tree */
} val; /* value */ } val; /* value */
int index; /* index for an array */ int index; /* index for an array */
union { union {
@ -673,16 +717,16 @@ struct tbl { /* table item */
* should be repoted by set/typeset). Does not include ARRAY or LOCAL. * should be repoted by set/typeset). Does not include ARRAY or LOCAL.
*/ */
#define USERATTRIB (EXPORT|INTEGER|RDONLY|LJUST|RJUST|ZEROFIL\ #define USERATTRIB (EXPORT|INTEGER|RDONLY|LJUST|RJUST|ZEROFIL\
|LCASEV|UCASEV_AL|INT_U|INT_L) |LCASEV|UCASEV_AL|INT_U|INT_L)
/* command types */ /* command types */
#define CNONE 0 /* undefined */ #define CNONE 0 /* undefined */
#define CSHELL 1 /* built-in */ #define CSHELL 1 /* built-in */
#define CFUNC 2 /* function */ #define CFUNC 2 /* function */
#define CEXEC 4 /* executable command */ #define CEXEC 4 /* executable command */
#define CALIAS 5 /* alias */ #define CALIAS 5 /* alias */
#define CKEYWD 6 /* keyword */ #define CKEYWD 6 /* keyword */
#define CTALIAS 7 /* tracked alias */ #define CTALIAS 7 /* tracked alias */
/* Flags for findcom()/comexec() */ /* Flags for findcom()/comexec() */
#define FC_SPECBI BIT(0) /* special builtin */ #define FC_SPECBI BIT(0) /* special builtin */
@ -702,7 +746,7 @@ struct tbl { /* table item */
/* Argument info. Used for $#, $* for shell, functions, includes, etc. */ /* Argument info. Used for $#, $* for shell, functions, includes, etc. */
struct arg_info { struct arg_info {
int flags; /* AF_* */ int flags; /* AF_* */
char **argv; const char **argv;
int argc_; int argc_;
int skip; /* first arg is argv[0], second is argv[1 + skip] */ int skip; /* first arg is argv[0], second is argv[1 + skip] */
}; };
@ -734,13 +778,12 @@ struct tstate {
struct tbl **next; struct tbl **next;
}; };
EXTERN struct table taliases; /* tracked aliases */
EXTERN struct table taliases; /* tracked aliases */ EXTERN struct table builtins; /* built-in commands */
EXTERN struct table builtins; /* built-in commands */ EXTERN struct table aliases; /* aliases */
EXTERN struct table aliases; /* aliases */ EXTERN struct table keywords; /* keywords */
EXTERN struct table keywords; /* keywords */
#ifndef MKSH_SMALL #ifndef MKSH_SMALL
EXTERN struct table homedirs; /* homedir() cache */ EXTERN struct table homedirs; /* homedir() cache */
#endif #endif
struct builtin { struct builtin {
@ -1103,16 +1146,16 @@ typedef union {
#define HERES 10 /* max << in line */ #define HERES 10 /* max << in line */
EXTERN Source *source; /* yyparse/yylex source */ EXTERN Source *source; /* yyparse/yylex source */
EXTERN YYSTYPE yylval; /* result from yylex */ EXTERN YYSTYPE yylval; /* result from yylex */
EXTERN struct ioword *heres [HERES], **herep; EXTERN struct ioword *heres [HERES], **herep;
EXTERN char ident [IDENT+1]; EXTERN char ident [IDENT+1];
#define HISTORYSIZE 500 /* size of saved history */ #define HISTORYSIZE 500 /* size of saved history */
EXTERN char **history; /* saved commands */ EXTERN char **history; /* saved commands */
EXTERN char **histptr; /* last history item */ EXTERN char **histptr; /* last history item */
EXTERN int histsize; /* history size */ EXTERN int histsize; /* history size */
/* alloc.c */ /* alloc.c */
Area *ainit(Area *); Area *ainit(Area *);

6
shf.c
View File

@ -2,7 +2,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.11 2007/01/15 02:48:28 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/shf.c,v 1.12 2007/03/04 03:04:27 tg Exp $");
/* flags to shf_emptybuf() */ /* flags to shf_emptybuf() */
#define EB_READSW 0x01 /* about to switch to reading */ #define EB_READSW 0x01 /* about to switch to reading */
@ -14,8 +14,8 @@ __RCSID("$MirOS: src/bin/mksh/shf.c,v 1.11 2007/01/15 02:48:28 tg Exp $");
* file descriptors. * file descriptors.
*/ */
static int shf_fillbuf(struct shf *); static int shf_fillbuf(struct shf *);
static int shf_emptybuf(struct shf *, int); static int shf_emptybuf(struct shf *, int);
/* Open a file. First three args are for open(), last arg is flags for /* Open a file. First three args are for open(), last arg is flags for
* this package. Returns NULL if file could not be opened, or if a dup * this package. Returns NULL if file could not be opened, or if a dup

View File

@ -1,5 +1,5 @@
#ifndef MKSH_SIGNAMES_CHECK #ifndef MKSH_SIGNAMES_CHECK
__RCSID("$MirOS: src/bin/mksh/signames.c,v 1.1 2007/01/12 00:25:40 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/signames.c,v 1.2 2007/03/04 03:04:28 tg Exp $");
#endif #endif
static const struct mksh_sigpair { static const struct mksh_sigpair {
@ -8,7 +8,7 @@ static const struct mksh_sigpair {
} mksh_sigpairs[] = { } mksh_sigpairs[] = {
#ifdef __Plan9__ #ifdef __Plan9__
... ...
#elif defined(__minix) #elif defined(__minix) && !defined(__GNUC__)
... ...
#elif defined(MKSH_SIGNAMES_CHECK) #elif defined(MKSH_SIGNAMES_CHECK)
#error no, must be OS supplied #error no, must be OS supplied

View File

@ -1,61 +0,0 @@
/* $OpenBSD: strcasestr.c,v 1.2 2005/08/08 08:05:37 espie Exp $ */
/* $NetBSD: strcasestr.c,v 1.2 2005/02/09 21:35:47 kleink Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/strcasestr.c,v 1.1 2006/11/12 13:15:27 tg Exp $");
/*
* Find the first occurrence of find in s, ignore case.
*/
char *
strcasestr(const char *s, const char *find)
{
char c, sc;
size_t len;
if ((c = *find++) != 0) {
c = ksh_tolower((unsigned char)c);
len = strlen(find);
do {
do {
if ((sc = *s++) == 0)
return (NULL);
} while ((char)ksh_tolower((unsigned char)sc) != c);
} while (strncasecmp(s, find, len) != 0);
s--;
}
return ((char *)s);
}

View File

@ -1,9 +1,15 @@
/* $MirOS: src/bin/mksh/strlfun.c,v 1.9 2007/01/12 01:49:29 tg Exp $ */ /* $MirOS: src/bin/mksh/strlcpy.c,v 1.1 2007/03/04 03:04:28 tg Exp $ */
/* $miros: src/lib/libc/string/strlfun.c,v 1.14 2007/01/07 02:11:40 tg Exp $ */ /* $miros: src/lib/libc/string/strlfun.c,v 1.14 2007/01/07 02:11:40 tg Exp $ */
/* $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */
/*- /*-
* Copyright (c) 2006 * Copyright (c) 2006, 2007
* Thorsten Glaser <tg@mirbsd.de> * Thorsten Glaser <tg@mirbsd.de>
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* *
* This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
* the utmost extent permitted by applicable law, neither express nor * the utmost extent permitted by applicable law, neither express nor
@ -13,62 +19,12 @@
* of dealing in the work, even if advised of the possibility of such * of dealing in the work, even if advised of the possibility of such
* damage or existence of a defect, except proven that it results out * damage or existence of a defect, except proven that it results out
* of said person's immediate fault when using the work as intended. * of said person's immediate fault when using the work as intended.
*-
* The strlcat() code below has been written by Thorsten Glaser. Bodo
* Eggert suggested optimising the strlcpy() code, originally written
* by Todd C. Miller (see below), which was carried out by Th. Glaser
* as well as merging this code with strxfrm() for ISO-10646-only sy-
* stems and writing wcslcat(), wcslcpy() and wcsxfrm() equivalents.
*/ */
#ifdef STRXFRM #include "sh.h"
#undef HAVE_STRLCPY
#undef HAVE_STRLCAT
#define HAVE_STRLCPY 0
#define HAVE_STRLCAT 1
#define strlcpy strxfrm
#endif
#include <sys/types.h> __RCSID("$MirOS: src/bin/mksh/strlcpy.c,v 1.1 2007/03/04 03:04:28 tg Exp $");
#if defined(_KERNEL) || defined(_STANDALONE)
#include <lib/libkern/libkern.h>
#undef HAVE_STRLCPY
#undef HAVE_STRLCAT
#else
#if defined(HAVE_CONFIG_H) && (HAVE_CONFIG_H != 0)
/* usually when packaged with third-party software */
#ifdef CONFIG_H_FILENAME
#include CONFIG_H_FILENAME
#else
#include "config.h"
#endif
#endif
#endif
#ifndef __predict_true
#define __predict_true(exp) ((exp) != 0)
#endif
#ifndef __predict_false
#define __predict_false(exp) ((exp) != 0)
#endif
#if !defined(_KERNEL) && !defined(_STANDALONE)
__RCSID("$MirOS: src/bin/mksh/strlfun.c,v 1.9 2007/01/12 01:49:29 tg Exp $");
#endif
size_t strlcpy(char *, const char *, size_t);
/* $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */
/*-
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*/
#if !defined(HAVE_STRLCPY) || (HAVE_STRLCPY == 0)
/* /*
* Copy src to string dst of size siz. At most siz-1 characters * Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0). * will be copied. Always NUL terminates (unless siz == 0).
@ -79,7 +35,7 @@ strlcpy(char *dst, const char *src, size_t siz)
{ {
const char *s = src; const char *s = src;
if (__predict_false(siz == 0)) if (siz == 0)
goto traverse_src; goto traverse_src;
/* copy as many chars as will fit */ /* copy as many chars as will fit */
@ -87,7 +43,7 @@ strlcpy(char *dst, const char *src, size_t siz)
; ;
/* not enough room in dst */ /* not enough room in dst */
if (__predict_false(siz == 0)) { if (siz == 0) {
/* safe to NUL-terminate dst since we copied <= siz-1 chars */ /* safe to NUL-terminate dst since we copied <= siz-1 chars */
*dst = '\0'; *dst = '\0';
traverse_src: traverse_src:
@ -99,4 +55,3 @@ strlcpy(char *dst, const char *src, size_t siz)
/* count doesn't include NUL */ /* count doesn't include NUL */
return (s - src - 1); return (s - src - 1);
} }
#endif /* !HAVE_STRLCPY */

6
syn.c
View File

@ -2,11 +2,11 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.11 2007/03/04 00:13:17 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/syn.c,v 1.12 2007/03/04 03:04:28 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) */
int start_line; /* line nesting began on */ int start_line; /* line nesting began on */
}; };
static void yyparse(void); static void yyparse(void);

14
tree.c
View File

@ -2,18 +2,18 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.8 2007/03/04 00:13:17 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/tree.c,v 1.9 2007/03/04 03:04:28 tg Exp $");
#define INDENT 4 #define INDENT 4
#define tputc(c, shf) shf_putchar(c, shf); #define tputc(c, shf) shf_putchar(c, shf);
static void ptree(struct op *, int, struct shf *); static void ptree(struct op *, int, struct shf *);
static void pioact(struct shf *, int, struct ioword *); static void pioact(struct shf *, int, struct ioword *);
static void tputC(int, struct shf *); static void tputC(int, struct shf *);
static void tputS(char *, struct shf *); static void tputS(char *, struct shf *);
static void vfptreef(struct shf *, int, const char *, va_list); static void vfptreef(struct shf *, int, const char *, va_list);
static struct ioword **iocopy(struct ioword **, Area *); static struct ioword **iocopy(struct ioword **, Area *);
static void iofree(struct ioword **, Area *); static void iofree(struct ioword **, Area *);
/* /*
* print a command tree * print a command tree

4
var.c
View File

@ -2,7 +2,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.36 2007/03/04 00:13:17 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/var.c,v 1.37 2007/03/04 03:04:28 tg Exp $");
/* /*
* Variables * Variables
@ -1139,7 +1139,7 @@ arrayname(const char *str)
{ {
const char *p; const char *p;
if ((p = strchr(str, '[')) == 0) if ((p = cstrchr(str, '[')) == 0)
/* Shouldn't happen, but why worry? */ /* Shouldn't happen, but why worry? */
return str_save(str, ATEMP); return str_save(str, ATEMP);