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