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

Reply via email to