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.
This commit is contained in:
parent
46a6e1093a
commit
f359a311bc
@ -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.c cd.c echo.c error.c eval.c exec.c \
|
||||
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
|
||||
|
@ -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 '@':
|
||||
|
147
bin/sh/mkoptions.sh
Normal file
147
bin/sh/mkoptions.sh
Normal file
@ -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
|
57
bin/sh/option.list
Normal file
57
bin/sh/option.list
Normal file
@ -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
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user