Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/bin/sh Arrange for set -o and $- output to be sorted, rather...



details:   https://anonhg.NetBSD.org/src/rev/06c8be798078
branches:  trunk
changeset: 824210:06c8be798078
user:      kre <kre%NetBSD.org@localhost>
date:      Sun May 28 00:38:01 2017 +0000

description:
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.

diffstat:

 bin/sh/Makefile     |    8 ++-
 bin/sh/expand.c     |   10 +-
 bin/sh/mkoptions.sh |  147 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 bin/sh/option.list  |   57 ++++++++++++++++++++
 bin/sh/options.h    |   76 +--------------------------
 5 files changed, 217 insertions(+), 81 deletions(-)

diffs (truncated from 362 to 300 lines):

diff -r 178d52c6227f -r 06c8be798078 bin/sh/Makefile
--- a/bin/sh/Makefile   Sun May 28 00:34:51 2017 +0000
+++ b/bin/sh/Makefile   Sun May 28 00:38:01 2017 +0000
@@ -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 @@
        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 @@
        ${_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
diff -r 178d52c6227f -r 06c8be798078 bin/sh/expand.c
--- a/bin/sh/expand.c   Sun May 28 00:34:51 2017 +0000
+++ b/bin/sh/expand.c   Sun May 28 00:38:01 2017 +0000
@@ -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 @@
                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 '@':
diff -r 178d52c6227f -r 06c8be798078 bin/sh/mkoptions.sh
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/sh/mkoptions.sh       Sun May 28 00:38:01 2017 +0000
@@ -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
diff -r 178d52c6227f -r 06c8be798078 bin/sh/option.list
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/sh/option.list        Sun May 28 00:38:01 2017 +0000
@@ -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
diff -r 178d52c6227f -r 06c8be798078 bin/sh/options.h
--- a/bin/sh/options.h  Sun May 28 00:34:51 2017 +0000
+++ b/bin/sh/options.h  Sun May 28 00:38:01 2017 +0000
@@ -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 @@
        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 */



Home | Main Index | Thread Index | Old Index