mkoptions.sh revision 1.1 1 #! /bin/sh
2
3 # $NetBSD: mkoptions.sh,v 1.1 2017/05/28 00:38:01 kre Exp $
4
5 #
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
8 # the externs (though they could just be explicit in options.h)
9 # and one just for options.c which generates the initialisation.
10 #
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.)
13
14 set -f
15 IFS=' ' # blank, tab (no newline)
16
17 IF="$1"
18 OF="${3+$3/}$2"
19
20 {
21 printf '/*\n * File automatically generated by %s.\n' "$0"
22 printf ' * Do not edit, do not add to cvs.\n'
23 printf ' */\n\n'
24
25 printf '#ifdef DEFINE_OPTIONS\n'
26 printf '#define DEF_OPT(a,b,c,d,e) { a, b, c, d, e },\n'
27 printf 'struct optent optlist[] = {\n'
28 printf '#else\n'
29 printf '#define DEF_OPT(a,b,c,d,e)\n'
30 printf '#endif\n\n'
31 } >"${OF}"
32
33 FIRST=true
34 I=0
35
36 while read line
37 do
38 # Look for comments in various styles, and ignore them
39 # preprocessor statements are simply output verbatim
40 # but use them only first or last. one #ifdef/#endif at end is OK
41
42 case "${line}" in
43 '') continue;;
44 /*) continue;;
45 \**) continue;;
46 \;*) continue;;
47 \#*) printf '%s\n\n' "${line}" >&4; continue;;
48 esac
49
50 set -- ${line%%[ ]#*}
51
52 var="$1" name="$2"
53
54 case "${var}" in
55 ('' | [!A-Za-z_]* | *[!A-Za-z0-9_]*)
56 printf >&2 "Bad var name: '%s'\\n" "${var}"
57 # exit 1
58 continue # just ignore it for now
59 esac
60
61 case "${name}" in
62 # =) name=${var};; # probably not a good idea
63 ?) set -- ${var} '' $name $3 $4; name= ;;
64 esac
65
66 chr="$3" set="$4" dflt="$5"
67
68 case "${chr}" in
69 -) chr= set= dflt="$4";;
70 ''|?) ;;
71 *) printf >&2 'flag "%s": Not a character\n' "${chr}"; continue;;
72 esac
73
74 # options must have some kind of name, or they are useless...
75 test -z "${name}${chr}" && continue
76
77 case "${set}" in
78 -) set= ;;
79 [01]) dflt="${set}"; set= ;;
80 ''|?) ;;
81 *) printf >&2 'set "%s": Not a character\n' "${set}"; continue;;
82 esac
83
84
85 if [ -n "${name}" ]
86 then
87 printf ' DEF_OPT("%s", ' "${name}" >&4
88 else
89 printf ' DEF_OPT(0, ' >&4
90 fi
91
92 if [ -n "${chr}" ]
93 then
94 printf "'%s', " "${chr}" >&4
95 else
96 printf '0, ' >&4
97 fi
98
99 if [ -n "${set}" ]
100 then
101 printf "'%s', 0, " "${set}" >&4
102 else
103 printf '0, 0, ' >&4
104 fi
105
106 if [ -n "${dflt}" ]
107 then
108 printf '%s )\n' "${dflt}" >&4
109 else
110 printf '0 )\n' >&4
111 fi
112
113 printf '#define %s optlist[%d].val\n\n' "${var}" "${I}" >&4
114 I=$((I + 1))
115
116 test -z "${chr}" && continue
117
118 printf '%s %d\n' "${chr}" $((I - 1))
119
120 done < "$IF" 4>>"${OF}" | sort -t' ' -k1,1f -k1,1r | while read chr index
121 do
122 if $FIRST
123 then
124 printf '#ifdef DEFINE_OPTIONS\n'
125 printf ' { 0, 0, 0, 0, 0 }\n};\n\n'
126 printf 'const unsigned char optorder[] = {\n'
127 FIRST=false
128 fi
129 printf '\t%s,\n' "${index}"
130
131 done >>"${OF}"
132
133 {
134 printf '};\n\n'
135 printf '#define NOPTS (sizeof optlist / sizeof optlist[0] - 1)\n'
136 printf 'int sizeof_optlist = sizeof optlist;\n\n'
137 printf \
138 'const int option_flags = (sizeof optorder / sizeof optorder[0]);\n'
139 printf '\n#else\n\n'
140 printf 'extern struct optent optlist[];\n'
141 printf 'extern int sizeof_optlist;\n'
142 printf 'extern const unsigned char optorder[];\n'
143 printf 'extern const int option_flags;\n'
144 printf '\n#endif\n'
145 } >> "${OF}"
146
147 exit 0
148