NetBSD/bin/sh/mkoptions.sh
kre 20c8eb69ec Sort options with long names that differ only by char case in
the same order that option flags with a similar property are sorted.
This corresponds with the change made to the sort order of the short
names made in the previous update (1.4).

Right now, this change makes no difference at all, as there are no
long option names that differ only in char case (yet.)
2017-11-15 09:21:19 +00:00

199 lines
4.0 KiB
Bash

#! /bin/sh
# $NetBSD: mkoptions.sh,v 1.5 2017/11/15 09:21:19 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"
E_FILE=$(${MKTEMP:-mktemp} -t MKO.E.$$)
O_FILE=$(${MKTEMP:-mktemp} -t MKO.O.$$)
trap 'rm -f "${E_FILE}" "${O_FILE}"' EXIT
exec 5> "${E_FILE}"
exec 6> "${O_FILE}"
{
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 'struct optent optlist[] = {\n'
} >"${OF}"
FIRST=true
${SED:-sed} <"${IF}" \
-e '/^$/d' \
-e '/^#/d' \
-e '/^[ ]*\//d' \
-e '/^[ ]*\*/d' \
-e '/^[ ]*;/d' |
sort -b -k2,2f -k2,2 < "${IF}" |
while read line
do
# Look for comments in various styles, and ignore them
# (these should generally be already removed by sed above)
case "${line}" in
'') continue;;
/*) continue;;
\**) continue;;
\;*) continue;;
\#*) continue;;
esac
case "${line}" in
*'#if'*)
COND="${line#*#}"
COND="#${COND%%#*}"
;;
*)
COND=
;;
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
?) 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] | [Oo][Nn] | [Oo][Ff][Ff]) dflt="${set}"; set= ;;
''|?) ;;
*) printf >&2 'set "%s": Not a character\n' "${set}"; continue;;
esac
case "${dflt}" in
'') ;;
[Oo][Nn]) dflt=1;;
[Oo][Ff][Ff]) dflt=0;;
[01]) ;;
*) printf >&2 'default "%s" invalid, use 0 off 1 on\n'; continue;;
esac
# validation complete, now to generate output
if [ -n "${COND}" ]
then
printf '%s\n' "${COND}" >&4
printf '%s\n' "${COND}" >&5
printf '%s\n' "${COND}" >&6
fi
printf '\t_SH_OPT_%s,\n' "${var}" >&5
if [ -n "${name}" ]
then
printf ' { "%s", ' "${name}" >&4
else
printf ' { 0, ' >&4
fi
if [ -n "${chr}" ]
then
printf "'%s', " "${chr}" >&4
else
chr=
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\toptlist[_SH_OPT_%s].val\n' "${var}" "${var}" >&6
if [ -n "${COND}" ]
then
printf '#endif\n' >&4
printf '#endif\n' >&5
printf '#endif\n' >&6
fi
test -z "${chr}" && continue
printf '%s _SH_OPT_%s %s\n' "${chr}" "${var}" "${COND}"
done 4>>"${OF}" | sort -t' ' -k1,1f -k1,1 | while read chr index COND
do
if $FIRST
then
printf ' { 0, 0, 0, 0, 0 }\n};\n'
printf '#endif\n\n'
printf 'enum shell_opt_names {\n'
cat "${E_FILE}"
printf '};\n\n'
printf '#ifdef DEFINE_OPTIONS\n'
printf 'const unsigned char optorder[] = {\n'
FIRST=false
fi
[ -n "${COND}" ] && printf '%s\n' "${COND}"
printf '\t%s,\n' "${index}"
[ -n "${COND}" ] && printf '#endif\n'
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\n'
cat "${O_FILE}"
} >> "${OF}"
exit 0