1f359a311Skre#! /bin/sh 2f359a311Skre 3*d434d049Skre# $NetBSD: mkoptions.sh,v 1.9 2024/10/11 08:53:09 kre Exp $ 4f359a311Skre 5f359a311Skre# 6f359a311Skre# It would be more sensible to generate 2 .h files, one which 7f359a311Skre# is for everyone to use, defines the "variables" and (perhaps) generates 8f359a311Skre# the externs (though they could just be explicit in options.h) 9f359a311Skre# and one just for options.c which generates the initialisation. 10f359a311Skre# 11f359a311Skre# But then I'd have to deal with making the Makefile handle that properly... 12f359a311Skre# (this is simpler there, and it just means a bit more sh compile time.) 13f359a311Skre 14f359a311Skreset -f 15f359a311SkreIFS=' ' # blank, tab (no newline) 163200c281Schristosexport LC_ALL=C # for sort consistency 17f359a311Skre 18f359a311SkreIF="$1" 19f359a311SkreOF="${3+$3/}$2" 20f359a311Skre 211568b401Skrecase $- in 221568b401Skre*x*) 231568b401Skre E_FILE=$(${MKTEMP:-mktemp} "${TMPDIR:-/tmp}/MKO.E.$$.XXXXXX") || exit 1 241568b401Skre O_FILE=$(${MKTEMP:-mktemp} "${TMPDIR:-/tmp}/MKO.O.$$.XXXXXX") || { 251568b401Skre rm -f "${E_FILE}" 261568b401Skre exit 1 271568b401Skre } 281568b401Skre ;; 291568b401Skre*) 301568b401Skre E_FILE=$(${MKTEMP:-mktemp}) || exit 1 311568b401Skre O_FILE=$(${MKTEMP:-mktemp}) || { rm -f "${E_FILE}"; exit 1; } 32d6a4153fSkre trap 'rm -f "${E_FILE}" "${O_FILE}"' EXIT 331568b401Skre ;; 341568b401Skreesac 35d6a4153fSkre 36d6a4153fSkreexec 5> "${E_FILE}" 37d6a4153fSkreexec 6> "${O_FILE}" 38d6a4153fSkre 39f359a311Skre{ 40f359a311Skre printf '/*\n * File automatically generated by %s.\n' "$0" 41f359a311Skre printf ' * Do not edit, do not add to cvs.\n' 42f359a311Skre printf ' */\n\n' 43f359a311Skre 44f359a311Skre printf '#ifdef DEFINE_OPTIONS\n' 45f359a311Skre printf 'struct optent optlist[] = {\n' 46f359a311Skre} >"${OF}" 47f359a311Skre 48f359a311SkreFIRST=true 49f359a311Skre 50d6a4153fSkre${SED:-sed} <"${IF}" \ 51d6a4153fSkre -e '/^$/d' \ 52d6a4153fSkre -e '/^#/d' \ 53d6a4153fSkre -e '/^[ ]*\//d' \ 54d6a4153fSkre -e '/^[ ]*\*/d' \ 55d6a4153fSkre -e '/^[ ]*;/d' | 56eda85bc1Schristossort -k2b,2f -k2b,2 | 57f359a311Skrewhile read line 58f359a311Skredo 59f359a311Skre # Look for comments in various styles, and ignore them 60d6a4153fSkre # (these should generally be already removed by sed above) 61f359a311Skre 62f359a311Skre case "${line}" in 63f359a311Skre '') continue;; 64f359a311Skre /*) continue;; 65f359a311Skre \**) continue;; 66f359a311Skre \;*) continue;; 67d6a4153fSkre \#*) continue;; 68f359a311Skre esac 69f359a311Skre 70d6a4153fSkre case "${line}" in 71d6a4153fSkre *'#if'*) 72d6a4153fSkre COND="${line#*#}" 73d6a4153fSkre COND="#${COND%%#*}" 74d6a4153fSkre ;; 75d6a4153fSkre *) 76d6a4153fSkre COND= 77d6a4153fSkre ;; 78d6a4153fSkre esac 79f359a311Skre set -- ${line%%[ ]#*} 80f359a311Skre 81f359a311Skre var="$1" name="$2" 82f359a311Skre 83f359a311Skre case "${var}" in 84f359a311Skre ('' | [!A-Za-z_]* | *[!A-Za-z0-9_]*) 85f359a311Skre printf >&2 "Bad var name: '%s'\\n" "${var}" 86f359a311Skre # exit 1 87f359a311Skre continue # just ignore it for now 88f359a311Skre esac 89f359a311Skre 90f359a311Skre case "${name}" in 91f359a311Skre ?) set -- ${var} '' $name $3 $4; name= ;; 92f359a311Skre esac 93f359a311Skre 94f359a311Skre chr="$3" set="$4" dflt="$5" 95f359a311Skre 96f359a311Skre case "${chr}" in 97f359a311Skre -) chr= set= dflt="$4";; 98*d434d049Skre +) chr= ;; 99f359a311Skre ''|?) ;; 100f359a311Skre *) printf >&2 'flag "%s": Not a character\n' "${chr}"; continue;; 101f359a311Skre esac 102f359a311Skre 103f359a311Skre # options must have some kind of name, or they are useless... 104f359a311Skre test -z "${name}${chr}" && continue 105f359a311Skre 106f359a311Skre case "${set}" in 107f359a311Skre -) set= ;; 108d6a4153fSkre [01] | [Oo][Nn] | [Oo][Ff][Ff]) dflt="${set}"; set= ;; 109f359a311Skre ''|?) ;; 110f359a311Skre *) printf >&2 'set "%s": Not a character\n' "${set}"; continue;; 111f359a311Skre esac 112f359a311Skre 113d6a4153fSkre case "${dflt}" in 114d6a4153fSkre '') ;; 115d6a4153fSkre [Oo][Nn]) dflt=1;; 116d6a4153fSkre [Oo][Ff][Ff]) dflt=0;; 117d6a4153fSkre [01]) ;; 118d6a4153fSkre *) printf >&2 'default "%s" invalid, use 0 off 1 on\n'; continue;; 119d6a4153fSkre esac 120d6a4153fSkre 121d6a4153fSkre # validation complete, now to generate output 122d6a4153fSkre 123d6a4153fSkre if [ -n "${COND}" ] 124d6a4153fSkre then 125d6a4153fSkre printf '%s\n' "${COND}" >&4 126d6a4153fSkre printf '%s\n' "${COND}" >&5 127d6a4153fSkre printf '%s\n' "${COND}" >&6 128d6a4153fSkre fi 129d6a4153fSkre 130d6a4153fSkre printf '\t_SH_OPT_%s,\n' "${var}" >&5 131f359a311Skre 132f359a311Skre if [ -n "${name}" ] 133f359a311Skre then 134d6a4153fSkre printf ' { "%s", ' "${name}" >&4 135f359a311Skre else 136d6a4153fSkre printf ' { 0, ' >&4 137f359a311Skre fi 138f359a311Skre 139f359a311Skre if [ -n "${chr}" ] 140f359a311Skre then 141f359a311Skre printf "'%s', " "${chr}" >&4 142f359a311Skre else 143d6a4153fSkre chr= 144f359a311Skre printf '0, ' >&4 145f359a311Skre fi 146f359a311Skre 147f359a311Skre if [ -n "${set}" ] 148f359a311Skre then 149f359a311Skre printf "'%s', 0, " "${set}" >&4 150f359a311Skre else 151f359a311Skre printf '0, 0, ' >&4 152f359a311Skre fi 153f359a311Skre 154f359a311Skre if [ -n "${dflt}" ] 155f359a311Skre then 156d6a4153fSkre printf '%s },\n' "${dflt}" >&4 157f359a311Skre else 158d6a4153fSkre printf '0 },\n' >&4 159f359a311Skre fi 160f359a311Skre 161d6a4153fSkre printf '#define %s\toptlist[_SH_OPT_%s].val\n' "${var}" "${var}" >&6 162d6a4153fSkre 163d6a4153fSkre if [ -n "${COND}" ] 164d6a4153fSkre then 165d6a4153fSkre printf '#endif\n' >&4 166d6a4153fSkre printf '#endif\n' >&5 167d6a4153fSkre printf '#endif\n' >&6 168d6a4153fSkre fi 169f359a311Skre 170f359a311Skre test -z "${chr}" && continue 171f359a311Skre 172d6a4153fSkre printf '%s _SH_OPT_%s %s\n' "${chr}" "${var}" "${COND}" 173f359a311Skre 1742ff69d1bSkredone 4>>"${OF}" | sort -t' ' -k1,1f -k1,1 | while read chr index COND 175f359a311Skredo 176f359a311Skre if $FIRST 177f359a311Skre then 178d6a4153fSkre printf ' { 0, 0, 0, 0, 0 }\n};\n' 179d6a4153fSkre printf '#endif\n\n' 180d6a4153fSkre 181d6a4153fSkre printf 'enum shell_opt_names {\n' 182d6a4153fSkre cat "${E_FILE}" 183d6a4153fSkre printf '};\n\n' 184d6a4153fSkre 185f359a311Skre printf '#ifdef DEFINE_OPTIONS\n' 186f359a311Skre printf 'const unsigned char optorder[] = {\n' 187f359a311Skre FIRST=false 188f359a311Skre fi 189d6a4153fSkre [ -n "${COND}" ] && printf '%s\n' "${COND}" 190f359a311Skre printf '\t%s,\n' "${index}" 191d6a4153fSkre [ -n "${COND}" ] && printf '#endif\n' 192f359a311Skre 193f359a311Skredone >>"${OF}" 194f359a311Skre 195f359a311Skre{ 196f359a311Skre printf '};\n\n' 197f359a311Skre printf '#define NOPTS (sizeof optlist / sizeof optlist[0] - 1)\n' 198f359a311Skre printf 'int sizeof_optlist = sizeof optlist;\n\n' 199f359a311Skre printf \ 200f359a311Skre 'const int option_flags = (sizeof optorder / sizeof optorder[0]);\n' 201f359a311Skre printf '\n#else\n\n' 202f359a311Skre printf 'extern struct optent optlist[];\n' 203f359a311Skre printf 'extern int sizeof_optlist;\n' 204f359a311Skre printf 'extern const unsigned char optorder[];\n' 205f359a311Skre printf 'extern const int option_flags;\n' 206d6a4153fSkre printf '\n#endif\n\n' 207d6a4153fSkre 208d6a4153fSkre cat "${O_FILE}" 209f359a311Skre} >> "${OF}" 210f359a311Skre 211f359a311Skreexit 0 212