Module Name: src Committed By: kre Date: Sun May 28 00:38:01 UTC 2017
Modified Files: src/bin/sh: Makefile expand.c options.h Added Files: src/bin/sh: mkoptions.sh option.list Log Message: Arrange for set -o and $- output to be sorted, rather than more or less random (and becoming worse as more options are added.) Since the data is known at compile time, sort at compile time, rather than at run time. To generate a diff of this commit: cvs rdiff -u -r1.107 -r1.108 src/bin/sh/Makefile cvs rdiff -u -r1.105 -r1.106 src/bin/sh/expand.c cvs rdiff -u -r0 -r1.1 src/bin/sh/mkoptions.sh src/bin/sh/option.list cvs rdiff -u -r1.26 -r1.27 src/bin/sh/options.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/bin/sh/Makefile diff -u src/bin/sh/Makefile:1.107 src/bin/sh/Makefile:1.108 --- src/bin/sh/Makefile:1.107 Mon May 15 18:34:56 2017 +++ src/bin/sh/Makefile Sun May 28 00:38:01 2017 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.107 2017/05/15 18:34:56 kre Exp $ +# $NetBSD: Makefile,v 1.108 2017/05/28 00:38:01 kre Exp $ # @(#)Makefile 8.4 (Berkeley) 5/5/95 .include <bsd.own.mk> @@ -9,7 +9,7 @@ SHSRCS= alias.c arith_token.c arithmetic miscbltin.c mystring.c options.c parser.c redir.c show.c trap.c \ output.c var.c test.c kill.c syntax.c GENSRCS=builtins.c init.c nodes.c -GENHDRS=builtins.h nodes.h token.h nodenames.h +GENHDRS=builtins.h nodes.h token.h nodenames.h optinit.h SRCS= ${SHSRCS} ${GENSRCS} DPSRCS+=${GENHDRS} @@ -77,6 +77,10 @@ nodenames.h: mknodenames.sh nodes.h ${_MKTARGET_CREATE} ${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC} > ${.TARGET} +optinit.h: mkoptions.sh option.list + ${_MKTARGET_CREATE} + ${SCRIPT_ENV} ${HOST_SH} ${.ALLSRC} ${.TARGET} ${.OBJDIR} + .if ${USETOOLS} == "yes" NBCOMPATLIB= -L${TOOLDIR}/lib -lnbcompat .endif Index: src/bin/sh/expand.c diff -u src/bin/sh/expand.c:1.105 src/bin/sh/expand.c:1.106 --- src/bin/sh/expand.c:1.105 Wed Apr 26 17:43:33 2017 +++ src/bin/sh/expand.c Sun May 28 00:38:01 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: expand.c,v 1.105 2017/04/26 17:43:33 christos Exp $ */ +/* $NetBSD: expand.c,v 1.106 2017/05/28 00:38:01 kre Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95"; #else -__RCSID("$NetBSD: expand.c,v 1.105 2017/04/26 17:43:33 christos Exp $"); +__RCSID("$NetBSD: expand.c,v 1.106 2017/05/28 00:38:01 kre Exp $"); #endif #endif /* not lint */ @@ -941,9 +941,9 @@ numvar: expdest = cvtnum(num, expdest); break; case '-': - for (i = 0; optlist[i].name || optlist[i].letter; i++) { - if (optlist[i].val && optlist[i].letter) - STPUTC(optlist[i].letter, expdest); + for (i = 0; i < option_flags; i++) { + if (optlist[optorder[i]].val) + STPUTC(optlist[optorder[i]].letter, expdest); } break; case '@': Index: src/bin/sh/options.h diff -u src/bin/sh/options.h:1.26 src/bin/sh/options.h:1.27 --- src/bin/sh/options.h:1.26 Thu May 18 13:53:18 2017 +++ src/bin/sh/options.h Sun May 28 00:38:01 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: options.h,v 1.26 2017/05/18 13:53:18 kre Exp $ */ +/* $NetBSD: options.h,v 1.27 2017/05/28 00:38:01 kre Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -55,79 +55,7 @@ struct optent { unsigned char dflt; /* default value of flag */ }; -/* Those marked [U] are required by posix, but have no effect! */ - -#ifdef DEFINE_OPTIONS -#define DEF_OPTS_D(name,letter,opt_set,dflt) {name, letter, opt_set, 0, dflt }, -struct optent optlist[] = { -#else -#define DEF_OPTS_D(name,letter,opt_set,dflt) -#endif -#define DEF_OPTS(name,letter,opt_set) DEF_OPTS_D(name, letter, opt_set, 0) -#define DEF_OPT(name,letter) DEF_OPTS_D(name, letter, 0, 0) -#define DEF_OPT_D(name,letter,dflt) DEF_OPTS_D(name, letter, 0, dflt) - -DEF_OPT( "errexit", 'e' ) /* exit on error */ -#define eflag optlist[0].val -DEF_OPT( "noglob", 'f' ) /* no pathname expansion */ -#define fflag optlist[1].val -DEF_OPT( "ignoreeof", 'I' ) /* do not exit on EOF */ -#define Iflag optlist[2].val -DEF_OPT( "interactive",'i' ) /* interactive shell */ -#define iflag optlist[3].val -DEF_OPT( "monitor", 'm' ) /* job control */ -#define mflag optlist[4].val -DEF_OPT( "noexec", 'n' ) /* do not exec commands */ -#define nflag optlist[5].val -DEF_OPT( "stdin", 's' ) /* read from stdin */ -#define sflag optlist[6].val -DEF_OPT( "xtrace", 'x' ) /* trace after expansion */ -#define xflag optlist[7].val -DEF_OPT( "verbose", 'v' ) /* trace read input */ -#define vflag optlist[8].val -DEF_OPTS( "vi", 'V', 'V' ) /* vi style editing */ -#define Vflag optlist[9].val -DEF_OPTS( "emacs", 'E', 'V' ) /* emacs style editing */ -#define Eflag optlist[10].val -DEF_OPT( "noclobber", 'C' ) /* do not overwrite files with > */ -#define Cflag optlist[11].val -DEF_OPT( "allexport", 'a' ) /* export all variables */ -#define aflag optlist[12].val -DEF_OPT( "notify", 'b' ) /* [U] report completion of background jobs */ -#define bflag optlist[13].val -DEF_OPT( "nounset", 'u' ) /* error expansion of unset variables */ -#define uflag optlist[14].val -DEF_OPT( "quietprofile", 'q' ) -#define qflag optlist[15].val -DEF_OPT( "nolog", 0 ) /* [U] no functon defs in command history */ -#define nolog optlist[16].val -DEF_OPT( "cdprint", 0 ) /* always print result of cd */ -#define cdprint optlist[17].val -DEF_OPT( "tabcomplete", 0 ) /* <tab> causes filename expansion */ -#define tabcomplete optlist[18].val -DEF_OPT( "fork", 'F' ) /* use fork(2) instead of vfork(2) */ -#define usefork optlist[19].val -DEF_OPT( "nopriv", 'p' ) /* preserve privs even if set{u,g}id */ -#define pflag optlist[20].val -DEF_OPT( "trackall", 'h' ) /* [U] locate cmds in funcs when defined */ -#define hflag optlist[21].val -DEF_OPT( "posix", 0 ) /* operate in posix mode */ -#define posix optlist[22].val -#ifdef DEBUG -DEF_OPT( "debug", 0 ) /* enable debug prints */ -#define debug optlist[23].val -#endif - -#ifdef DEFINE_OPTIONS - { 0, 0, 0, 0, 0 }, -}; -#define NOPTS (sizeof optlist / sizeof optlist[0] - 1) -int sizeof_optlist = sizeof optlist; -#else -extern struct optent optlist[]; -extern int sizeof_optlist; -#endif - +#include "optinit.h" extern char *minusc; /* argument to -c option */ extern char *arg0; /* $0 */ Added files: Index: src/bin/sh/mkoptions.sh diff -u /dev/null src/bin/sh/mkoptions.sh:1.1 --- /dev/null Sun May 28 00:38:01 2017 +++ src/bin/sh/mkoptions.sh Sun May 28 00:38:01 2017 @@ -0,0 +1,147 @@ +#! /bin/sh + +# $NetBSD: mkoptions.sh,v 1.1 2017/05/28 00:38:01 kre Exp $ + +# +# It would be more sensible to generate 2 .h files, one which +# is for everyone to use, defines the "variables" and (perhaps) generates +# the externs (though they could just be explicit in options.h) +# and one just for options.c which generates the initialisation. +# +# But then I'd have to deal with making the Makefile handle that properly... +# (this is simpler there, and it just means a bit more sh compile time.) + +set -f +IFS=' ' # blank, tab (no newline) + +IF="$1" +OF="${3+$3/}$2" + +{ + printf '/*\n * File automatically generated by %s.\n' "$0" + printf ' * Do not edit, do not add to cvs.\n' + printf ' */\n\n' + + printf '#ifdef DEFINE_OPTIONS\n' + printf '#define DEF_OPT(a,b,c,d,e) { a, b, c, d, e },\n' + printf 'struct optent optlist[] = {\n' + printf '#else\n' + printf '#define DEF_OPT(a,b,c,d,e)\n' + printf '#endif\n\n' +} >"${OF}" + +FIRST=true +I=0 + +while read line +do + # Look for comments in various styles, and ignore them + # preprocessor statements are simply output verbatim + # but use them only first or last. one #ifdef/#endif at end is OK + + case "${line}" in + '') continue;; + /*) continue;; + \**) continue;; + \;*) continue;; + \#*) printf '%s\n\n' "${line}" >&4; continue;; + esac + + set -- ${line%%[ ]#*} + + var="$1" name="$2" + + case "${var}" in + ('' | [!A-Za-z_]* | *[!A-Za-z0-9_]*) + printf >&2 "Bad var name: '%s'\\n" "${var}" + # exit 1 + continue # just ignore it for now + esac + + case "${name}" in +# =) name=${var};; # probably not a good idea + ?) set -- ${var} '' $name $3 $4; name= ;; + esac + + chr="$3" set="$4" dflt="$5" + + case "${chr}" in + -) chr= set= dflt="$4";; + ''|?) ;; + *) printf >&2 'flag "%s": Not a character\n' "${chr}"; continue;; + esac + + # options must have some kind of name, or they are useless... + test -z "${name}${chr}" && continue + + case "${set}" in + -) set= ;; + [01]) dflt="${set}"; set= ;; + ''|?) ;; + *) printf >&2 'set "%s": Not a character\n' "${set}"; continue;; + esac + + + if [ -n "${name}" ] + then + printf ' DEF_OPT("%s", ' "${name}" >&4 + else + printf ' DEF_OPT(0, ' >&4 + fi + + if [ -n "${chr}" ] + then + printf "'%s', " "${chr}" >&4 + else + printf '0, ' >&4 + fi + + if [ -n "${set}" ] + then + printf "'%s', 0, " "${set}" >&4 + else + printf '0, 0, ' >&4 + fi + + if [ -n "${dflt}" ] + then + printf '%s )\n' "${dflt}" >&4 + else + printf '0 )\n' >&4 + fi + + printf '#define %s optlist[%d].val\n\n' "${var}" "${I}" >&4 + I=$((I + 1)) + + test -z "${chr}" && continue + + printf '%s %d\n' "${chr}" $((I - 1)) + +done < "$IF" 4>>"${OF}" | sort -t' ' -k1,1f -k1,1r | while read chr index +do + if $FIRST + then + printf '#ifdef DEFINE_OPTIONS\n' + printf ' { 0, 0, 0, 0, 0 }\n};\n\n' + printf 'const unsigned char optorder[] = {\n' + FIRST=false + fi + printf '\t%s,\n' "${index}" + +done >>"${OF}" + +{ + printf '};\n\n' + printf '#define NOPTS (sizeof optlist / sizeof optlist[0] - 1)\n' + printf 'int sizeof_optlist = sizeof optlist;\n\n' + printf \ + 'const int option_flags = (sizeof optorder / sizeof optorder[0]);\n' + printf '\n#else\n\n' + printf 'extern struct optent optlist[];\n' + printf 'extern int sizeof_optlist;\n' + printf 'extern const unsigned char optorder[];\n' + printf 'extern const int option_flags;\n' + printf '\n#endif\n' +} >> "${OF}" + +exit 0 Index: src/bin/sh/option.list diff -u /dev/null src/bin/sh/option.list:1.1 --- /dev/null Sun May 28 00:38:01 2017 +++ src/bin/sh/option.list Sun May 28 00:38:01 2017 @@ -0,0 +1,57 @@ +/* $NetBSD: option.list,v 1.1 2017/05/28 00:38:01 kre Exp $ */ + +/* + * define the shell's settable options + */ + +/* + * format is up to 5 columns... (followed by anything) + * end of line comments can be introduced by ' #' (space/tab hash) to eol. + * proprocessor directoves can be (kind of) interspersed as required + * + * The columns are: + * 1. internal shell "var name" (required) + * 2. option long name + * if a single char, then no long name, and remaining + * columns shift left (this becomes the short name) + * 3. option short name (single character name) + * if '-' or absent then no short name + * if neither long nor short name, line is ignored + * 4. option set short name (name of option equiv class) + * if '-' or absent then no class + * 5. efault value of option + * if absent, default is 0 + * only 0 or 1 possible (0==off 1==on) + */ + +/* + * The order of the lines below gives the order they are listed by set -o + * Options labelled '[U]' are not (yet, maybe ever) implemented. + */ +aflag allexport a # export all variables +cdprint cdprint # always print result of a cd +Eflag emacs E V # enable emacs style editing +eflag errexit e # exit on command error ($? != 0) +usefork fork F # use fork(2) instead of vfork(2) +Iflag ignoreeof I # do not exit interactive shell on EOF +iflag interactive i # interactive shell +mflag monitor m # enable job control +Cflag noclobber C # do not overwrite files when using > +nflag noexec n # do not execue commands +fflag noglob f # no pathname expansion +nolog nolog # [U] no func definitions in history +pflag nopriv p # preserve privs if set[ug]id +bflag notify b # [U] report bg job completion +uflag nounset u # expanding unset var is an error +posix posix # be closer to POSIX compat +qflag quietprofile q # disable -v/-x in startup files +sflag stdin s # read from standard input +tabcomplete tabcomplete # make <tab> cause filename expansion +hflag trackall h # [U] locate cmds in funcs during defn +vflag verbose v # echo commands as read +Vflag vi V V # enable vi style editing +xflag xtrace x # trace command execution + +#ifdef DEBUG +debug debug # enable internal shell debugging +#endif