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