summaryrefslogtreecommitdiff
path: root/bin/sh/mkoptions.sh
diff options
context:
space:
mode:
authorKiyoshi Aman <kiyoshi.aman+adelie@gmail.com>2019-02-01 22:55:37 +0000
committerKiyoshi Aman <kiyoshi.aman+adelie@gmail.com>2019-02-03 18:22:05 -0600
commit5b57d28ffb6e1ef86b50f7d05d977826eae89bfe (patch)
tree154a22fe556b49e6927197336f8bf91b12eacd5e /bin/sh/mkoptions.sh
downloaduserland-5b57d28ffb6e1ef86b50f7d05d977826eae89bfe.tar.gz
userland-5b57d28ffb6e1ef86b50f7d05d977826eae89bfe.tar.bz2
userland-5b57d28ffb6e1ef86b50f7d05d977826eae89bfe.tar.xz
userland-5b57d28ffb6e1ef86b50f7d05d977826eae89bfe.zip
initial population
Diffstat (limited to 'bin/sh/mkoptions.sh')
-rw-r--r--bin/sh/mkoptions.sh198
1 files changed, 198 insertions, 0 deletions
diff --git a/bin/sh/mkoptions.sh b/bin/sh/mkoptions.sh
new file mode 100644
index 0000000..aecb6df
--- /dev/null
+++ b/bin/sh/mkoptions.sh
@@ -0,0 +1,198 @@
+#! /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