diff --git a/Build.sh b/Build.sh index 778cbf1..feac5d6 100644 --- a/Build.sh +++ b/Build.sh @@ -1,5 +1,5 @@ #!/bin/sh -srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.649 2013/11/17 22:21:16 tg Exp $' +srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.650 2013/11/17 22:22:50 tg Exp $' #- # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013 @@ -1602,7 +1602,7 @@ else #define EXTERN #define MKSH_INCLUDES_ONLY #include "sh.h" - __RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.649 2013/11/17 22:21:16 tg Exp $"); + __RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.650 2013/11/17 22:22:50 tg Exp $"); int main(void) { printf("Hello, World!\n"); return (0); } EOF case $cm in @@ -2257,7 +2257,7 @@ echo tcfn=$mkshexe >>Rebuild.sh echo "$CC $CFLAGS $LDFLAGS -o \$tcfn $lobjs $LIBS $ccpr" >>Rebuild.sh echo "test -f \$tcfn || exit 1; $SIZE \$tcfn" >>Rebuild.sh if test $cm = makefile; then - extras='emacsfn.h genopt.sh rlimits.opt sh.h sh_flags.h var_spec.h' + extras='emacsfn.h genopt.sh rlimits.opt sh.h sh_flags.opt var_spec.h' test 0 = $HAVE_SYS_SIGNAME && extras="$extras signames.inc" cat >Makefrag.inc < @@ -74,6 +74,25 @@ soptc() { o_str=$o_str$nl"<$optclo$islo$sym" } +scond() { + case x$cond in + x) + cond= + ;; + x*' '*) + cond=`echo "$cond" | sed 's/^ //'` + cond="#if $cond" + ;; + x'!'*) + cond=`echo "$cond" | sed 's/^!//'` + cond="#ifndef $cond" + ;; + x*) + cond="#ifdef $cond" + ;; + esac +} + for srcfile do bn=`basename "$srcfile" | sed 's/.opt$//'` @@ -127,11 +146,7 @@ do 2:'>'*'|'*) soptc cond=`echo "$line" | sed 's/^[^|]*|//'` - case x$cond in - x) cond= ;; - x*' '*) cond="#if $cond" ;; - x*) cond="#ifdef $cond" ;; - esac + scond case $optc in '|') optc=0 ;; *) optc=\'$optc\' ;; @@ -150,11 +165,7 @@ do esac echo "$o_str" | sort | while IFS='|' read -r x opts cond; do test -n "$x" || continue - case x$cond in - x) cond= ;; - x*' '*) cond="#if $cond" ;; - x*) cond="#ifdef $cond" ;; - esac + scond test -n "$cond" && echo "$cond" echo "\"$opts\"" test -n "$cond" && echo "#endif" diff --git a/misc.c b/misc.c index 195691d..0487664 100644 --- a/misc.c +++ b/misc.c @@ -30,7 +30,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.216 2013/10/09 11:59:29 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.217 2013/11/17 22:22:53 tg Exp $"); #define KSH_CHVT_FLAG #ifdef MKSH_SMALL @@ -125,7 +125,7 @@ Xcheck_grow(XString *xsp, const char *xp, size_t more) #define SHFLAGS_DEFNS -#include "sh_flags.h" +#include "sh_flags.gen" #define OFC(i) (options[i][-2]) #define OFF(i) (((const unsigned char *)options[i])[-1]) @@ -133,7 +133,7 @@ Xcheck_grow(XString *xsp, const char *xp, size_t more) const char * const options[] = { #define SHFLAGS_ITEMS -#include "sh_flags.h" +#include "sh_flags.gen" }; /* @@ -341,10 +341,20 @@ parse_args(const char **argv, int what, bool *setargsp) { - static char cmd_opts[NELEM(options) + 5]; /* o:T:\0 */ - static char set_opts[NELEM(options) + 6]; /* A:o;s\0 */ + static const char cmd_opts[] = +#define SHFLAGS_NOT_SET +#define SHFLAGS_OPTCS +#include "sh_flags.gen" +#undef SHFLAGS_NOT_SET + ; + static const char set_opts[] = +#define SHFLAGS_NOT_CMD +#define SHFLAGS_OPTCS +#include "sh_flags.gen" +#undef SHFLAGS_NOT_CMD + ; bool set; - char *opts; + const char *opts; const char *array = NULL; Getopt go; size_t i; @@ -352,36 +362,6 @@ parse_args(const char **argv, bool sortargs = false; bool fcompatseen = false; - /* First call? Build option strings... */ - if (cmd_opts[0] == '\0') { - char ch, *p = cmd_opts, *q = set_opts; - - /* see cmd_opts[] declaration */ - *p++ = 'o'; - *p++ = ':'; -#ifdef KSH_CHVT_FLAG - *p++ = 'T'; - *p++ = ':'; -#endif - /* see set_opts[] declaration */ - *q++ = 'A'; - *q++ = ':'; - *q++ = 'o'; - *q++ = ';'; - *q++ = 's'; - - for (i = 0; i < NELEM(options); i++) { - if ((ch = OFC(i))) { - if (OFF(i) & OF_CMDLINE) - *p++ = ch; - if (OFF(i) & OF_SET) - *q++ = ch; - } - } - *p = '\0'; - *q = '\0'; - } - if (what == OF_CMDLINE) { const char *p = argv[0], *q; /* diff --git a/sh.h b/sh.h index f9f9e47..e52977d 100644 --- a/sh.h +++ b/sh.h @@ -164,7 +164,7 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.673 2013/10/31 20:05:39 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.674 2013/11/17 22:22:54 tg Exp $"); #endif #define MKSH_VERSION "R48 2013/10/08" @@ -664,7 +664,7 @@ EXTERN Area aperm; /* permanent object space */ */ enum sh_flag { #define SHFLAGS_ENUMS -#include "sh_flags.h" +#include "sh_flags.gen" FNFLAGS /* (place holder: how many flags are there) */ }; diff --git a/sh_flags.h b/sh_flags.h deleted file mode 100644 index 3e4cf56..0000000 --- a/sh_flags.h +++ /dev/null @@ -1,166 +0,0 @@ -#if defined(SHFLAGS_DEFNS) -__RCSID("$MirOS: src/bin/mksh/sh_flags.h,v 1.16 2013/08/11 14:57:11 tg Exp $"); -#define FN(sname,cname,ochar,flags) \ - static const struct { \ - /* character flag (if any) */ \ - char c; \ - /* OF_* */ \ - unsigned char optflags; \ - /* long name of option */ \ - char name[sizeof(sname)]; \ - } shoptione_ ## cname = { \ - ochar, flags, sname \ - }; -#elif defined(SHFLAGS_ENUMS) -#define FN(sname,cname,ochar,flags) cname, -#define F0(sname,cname,ochar,flags) cname = 0, -#elif defined(SHFLAGS_ITEMS) -#define FN(sname,cname,ochar,flags) \ - ((const char *)(&shoptione_ ## cname)) + 2, -#endif - -#ifndef F0 -#define F0 FN -#endif - -/* - * special cases (see parse_args()): -A, -o, -s - * - * options are sorted by their longnames - */ - -/* -a all new parameters are created with the export attribute */ -F0("allexport", FEXPORT, 'a', OF_ANY) - -#if HAVE_NICE -/* ./. bgnice */ -FN("bgnice", FBGNICE, 0, OF_ANY) -#endif - -/* ./. enable {} globbing (non-standard) */ -FN("braceexpand", FBRACEEXPAND, 0, OF_ANY) - -#if !defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE) -/* ./. Emacs command line editing mode */ -FN("emacs", FEMACS, 0, OF_ANY) -#endif - -/* -e quit on error */ -FN("errexit", FERREXIT, 'e', OF_ANY) - -#if !defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE) -/* ./. Emacs command line editing mode, gmacs variant */ -FN("gmacs", FGMACS, 0, OF_ANY) -#endif - -/* ./. reading EOF does not exit */ -FN("ignoreeof", FIGNOREEOF, 0, OF_ANY) - -/* ./. inherit -x flag */ -FN("inherit-xtrace", FXTRACEREC, 0, OF_ANY) - -/* -i interactive shell */ -FN("interactive", FTALKING, 'i', OF_CMDLINE) - -/* -k name=value are recognised anywhere */ -FN("keyword", FKEYWORD, 'k', OF_ANY) - -/* -l login shell */ -FN("login", FLOGIN, 'l', OF_CMDLINE) - -/* -X mark dirs with / in file name completion */ -FN("markdirs", FMARKDIRS, 'X', OF_ANY) - -#ifndef MKSH_UNEMPLOYED -/* -m job control monitoring */ -FN("monitor", FMONITOR, 'm', OF_ANY) -#endif - -/* -C don't overwrite existing files */ -FN("noclobber", FNOCLOBBER, 'C', OF_ANY) - -/* -n don't execute any commands */ -FN("noexec", FNOEXEC, 'n', OF_ANY) - -/* -f don't do file globbing */ -FN("noglob", FNOGLOB, 'f', OF_ANY) - -/* ./. don't kill running jobs when login shell exits */ -FN("nohup", FNOHUP, 0, OF_ANY) - -/* ./. don't save functions in history (no effect) */ -FN("nolog", FNOLOG, 0, OF_ANY) - -#ifndef MKSH_UNEMPLOYED -/* -b asynchronous job completion notification */ -FN("notify", FNOTIFY, 'b', OF_ANY) -#endif - -/* -u using an unset variable is an error */ -FN("nounset", FNOUNSET, 'u', OF_ANY) - -/* ./. don't do logical cds/pwds (non-standard) */ -FN("physical", FPHYSICAL, 0, OF_ANY) - -/* ./. errorlevel of a pipeline is the rightmost nonzero value */ -FN("pipefail", FPIPEFAIL, 0, OF_ANY) - -/* ./. adhere more closely to POSIX even when undesirable */ -FN("posix", FPOSIX, 0, OF_ANY) - -/* -p use suid_profile; privileged shell */ -FN("privileged", FPRIVILEGED, 'p', OF_ANY) - -/* -r restricted shell */ -FN("restricted", FRESTRICTED, 'r', OF_CMDLINE) - -/* ./. kludge mode for better compat with traditional sh (OS-specific) */ -FN("sh", FSH, 0, OF_ANY) - -/* -s (invocation) parse stdin (pseudo non-standard) */ -FN("stdin", FSTDIN, 's', OF_CMDLINE) - -/* -h create tracked aliases for all commands */ -FN("trackall", FTRACKALL, 'h', OF_ANY) - -/* -U enable UTF-8 processing (non-standard) */ -FN("utf8-mode", FUNICODE, 'U', OF_ANY) - -/* -v echo input */ -FN("verbose", FVERBOSE, 'v', OF_ANY) - -#if !defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE) -/* ./. Vi command line editing mode */ -FN("vi", FVI, 0, OF_ANY) - -/* ./. enable ESC as file name completion character (non-standard) */ -FN("vi-esccomplete", FVIESCCOMPLETE, 0, OF_ANY) - -/* ./. enable Tab as file name completion character (non-standard) */ -FN("vi-tabcomplete", FVITABCOMPLETE, 0, OF_ANY) - -/* ./. always read in raw mode (no effect) */ -FN("viraw", FVIRAW, 0, OF_ANY) -#endif - -/* -x execution trace (display commands as they are run) */ -FN("xtrace", FXTRACE, 'x', OF_ANY) - -/* -c (invocation) execute specified command */ -FN("", FCOMMAND, 'c', OF_CMDLINE) - -/* - * anonymous flags: used internally by shell only (not visible to user) - */ - -/* ./. direct builtin call (divined from argv[0] multi-call binary) */ -FN("", FAS_BUILTIN, 0, OF_INTERNAL) - -/* ./. (internal) initial shell was interactive */ -FN("", FTALKING_I, 0, OF_INTERNAL) - -#undef FN -#undef F0 -#undef SHFLAGS_DEFNS -#undef SHFLAGS_ENUMS -#undef SHFLAGS_ITEMS diff --git a/sh_flags.opt b/sh_flags.opt new file mode 100644 index 0000000..036074a --- /dev/null +++ b/sh_flags.opt @@ -0,0 +1,190 @@ +@SHFLAGS_DEFNS +__RCSID("$MirOS: src/bin/mksh/sh_flags.opt,v 1.1 2013/11/17 22:22:56 tg Exp $"); +#define FN(sname,cname,flags,ochar) \ + static const struct { \ + /* character flag (if any) */ \ + char c; \ + /* OF_* */ \ + unsigned char optflags; \ + /* long name of option */ \ + char name[sizeof(sname)]; \ + } shoptione_ ## cname = { \ + ochar, flags, sname \ + }; +@SHFLAGS_ENUMS +#define FN(sname,cname,flags,ochar) cname, +#define F0(sname,cname,flags,ochar) cname = 0, +@SHFLAGS_ITEMS +#define FN(sname,cname,flags,ochar) \ + ((const char *)(&shoptione_ ## cname)) + 2, +@@ + +/* special cases */ + +a| +F0("allexport", FEXPORT, OF_ANY + +/* ./. bgnice */ +>| HAVE_NICE +FN("bgnice", FBGNICE, OF_ANY + +/* ./. enable {} globbing (non-standard) */ +>| +FN("braceexpand", FBRACEEXPAND, OF_ANY + +/* ./. Emacs command line editing mode */ +>|!defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE) +FN("emacs", FEMACS, OF_ANY + +/* -e quit on error */ +>e| +FN("errexit", FERREXIT, OF_ANY + +/* ./. Emacs command line editing mode, gmacs variant */ +>|!defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE) +FN("gmacs", FGMACS, OF_ANY + +/* ./. reading EOF does not exit */ +>| +FN("ignoreeof", FIGNOREEOF, OF_ANY + +/* ./. inherit -x flag */ +>| +FN("inherit-xtrace", FXTRACEREC, OF_ANY + +/* -i interactive shell */ +>i|!SHFLAGS_NOT_CMD +FN("interactive", FTALKING, OF_CMDLINE + +/* -k name=value are recognised anywhere */ +>k| +FN("keyword", FKEYWORD, OF_ANY + +/* -l login shell */ +>l|!SHFLAGS_NOT_CMD +FN("login", FLOGIN, OF_CMDLINE + +/* -X mark dirs with / in file name completion */ +>X| +FN("markdirs", FMARKDIRS, OF_ANY + +/* -m job control monitoring */ +>m|!MKSH_UNEMPLOYED +FN("monitor", FMONITOR, OF_ANY + +/* -C don't overwrite existing files */ +>C| +FN("noclobber", FNOCLOBBER, OF_ANY + +/* -n don't execute any commands */ +>n| +FN("noexec", FNOEXEC, OF_ANY + +/* -f don't do file globbing */ +>f| +FN("noglob", FNOGLOB, OF_ANY + +/* ./. don't kill running jobs when login shell exits */ +>| +FN("nohup", FNOHUP, OF_ANY + +/* ./. don't save functions in history (no effect) */ +>| +FN("nolog", FNOLOG, OF_ANY + +/* -b asynchronous job completion notification */ +>b|!MKSH_UNEMPLOYED +FN("notify", FNOTIFY, OF_ANY + +/* -u using an unset variable is an error */ +>u| +FN("nounset", FNOUNSET, OF_ANY + +/* ./. don't do logical cds/pwds (non-standard) */ +>| +FN("physical", FPHYSICAL, OF_ANY + +/* ./. errorlevel of a pipeline is the rightmost nonzero value */ +>| +FN("pipefail", FPIPEFAIL, OF_ANY + +/* ./. adhere more closely to POSIX even when undesirable */ +>| +FN("posix", FPOSIX, OF_ANY + +/* -p use suid_profile; privileged shell */ +>p| +FN("privileged", FPRIVILEGED, OF_ANY + +/* -r restricted shell */ +>r|!SHFLAGS_NOT_CMD +FN("restricted", FRESTRICTED, OF_CMDLINE + +/* ./. kludge mode for better compat with traditional sh (OS-specific) */ +>| +FN("sh", FSH, OF_ANY + +/* -s (invocation) parse stdin (pseudo non-standard) */ +>s|!SHFLAGS_NOT_CMD +FN("stdin", FSTDIN, OF_CMDLINE + +/* -h create tracked aliases for all commands */ +>h| +FN("trackall", FTRACKALL, OF_ANY + +/* -U enable UTF-8 processing (non-standard) */ +>U| +FN("utf8-mode", FUNICODE, OF_ANY + +/* -v echo input */ +>v| +FN("verbose", FVERBOSE, OF_ANY + +/* ./. Vi command line editing mode */ +>|!defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE) +FN("vi", FVI, OF_ANY + +/* ./. enable ESC as file name completion character (non-standard) */ +>|!defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE) +FN("vi-esccomplete", FVIESCCOMPLETE, OF_ANY + +/* ./. enable Tab as file name completion character (non-standard) */ +>|!defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE) +FN("vi-tabcomplete", FVITABCOMPLETE, OF_ANY + +/* ./. always read in raw mode (no effect) */ +>|!defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE) +FN("viraw", FVIRAW, OF_ANY + +/* -x execution trace (display commands as they are run) */ +>x| +FN("xtrace", FXTRACE, OF_ANY + +/* -c (invocation) execute specified command */ +>c|!SHFLAGS_NOT_CMD +FN("", FCOMMAND, OF_CMDLINE + +/* + * anonymous flags: used internally by shell only (not visible to user + */ + +/* ./. direct builtin call (divined from argv[0] multi-call binary) */ +>| +FN("", FAS_BUILTIN, OF_INTERNAL + +/* ./. (internal) initial shell was interactive */ +>| +FN("", FTALKING_I, OF_INTERNAL + +|SHFLAGS_OPTCS