20c8eb69ec
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.)
199 lines
4.0 KiB
Bash
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
|