et_c.awk revision 65f0aab98b20b5994a726ab90d355248bcddfffd
1BEGIN { 
2if ( length(outfn) == 0) {
3	outfn = outfile
4}
5char_shift=64
6## "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
7c2n["A"]=1
8c2n["B"]=2
9c2n["C"]=3
10c2n["D"]=4
11c2n["E"]=5
12c2n["F"]=6
13c2n["G"]=7
14c2n["H"]=8
15c2n["I"]=9
16c2n["J"]=10
17c2n["K"]=11
18c2n["L"]=12
19c2n["M"]=13
20c2n["N"]=14
21c2n["O"]=15
22c2n["P"]=16
23c2n["Q"]=17
24c2n["R"]=18
25c2n["S"]=19
26c2n["T"]=20
27c2n["U"]=21
28c2n["V"]=22
29c2n["W"]=23
30c2n["X"]=24
31c2n["Y"]=25
32c2n["Z"]=26
33c2n["a"]=27
34c2n["b"]=28
35c2n["c"]=29
36c2n["d"]=30
37c2n["e"]=31
38c2n["f"]=32
39c2n["g"]=33
40c2n["h"]=34
41c2n["i"]=35
42c2n["j"]=36
43c2n["k"]=37
44c2n["l"]=38
45c2n["m"]=39
46c2n["n"]=40
47c2n["o"]=41
48c2n["p"]=42
49c2n["q"]=43
50c2n["r"]=44
51c2n["s"]=45
52c2n["t"]=46
53c2n["u"]=47
54c2n["v"]=48
55c2n["w"]=49
56c2n["x"]=50
57c2n["y"]=51
58c2n["z"]=52
59c2n["0"]=53
60c2n["1"]=54
61c2n["2"]=55
62c2n["3"]=56
63c2n["4"]=57
64c2n["5"]=58
65c2n["6"]=59
66c2n["7"]=60
67c2n["8"]=61
68c2n["9"]=62
69c2n["_"]=63
70}
71/^#/ { next }
72/^[ \t]*(error_table|et)[ \t]+[a-zA-Z][a-zA-Z0-9_]+/ {
73	table_number = 0
74	mod_base = 1000000
75	if (NF > 2) {
76	    table_name = $3
77	    base_name = $2
78	} else {
79	    table_name = $2
80	    base_name = table_name
81	}
82	for(i=1; i<=length(base_name); i++) {
83	    table_number=(table_number*char_shift)+c2n[substr(base_name,i,1)]
84	}
85
86	# We start playing *_high, *low games here because the some
87	# awk programs do not have the necessary precision (sigh)
88	tab_base_low = table_number % mod_base
89	if (tab_base_low < 0) {
90		# Work around stupid bug in the ARM libm
91		tab_base_low = tab_base_low + mod_base
92	}
93	tab_base_high = int(table_number / mod_base)
94	tab_base_sign = 1;
95
96	# figure out: table_number_base=table_number*256
97	tab_base_low = tab_base_low * 256
98	tab_base_high = (tab_base_high * 256) + \
99			int(tab_base_low / mod_base)
100	tab_base_low = tab_base_low % mod_base
101	if (tab_base_low < 0) {
102		# Work around stupid bug in the ARM libm
103		tab_base_low = tab_base_low + mod_base
104	}
105
106	if (table_number > 128*256*256) {
107		# figure out:  table_number_base -= 256*256*256*256
108		# sub_high, sub_low is 256*256*256*256
109		sub_low = 256*256*256 % mod_base
110		sub_high = int(256*256*256 / mod_base)
111
112		sub_low = sub_low * 256
113		sub_high = (sub_high * 256) + int(sub_low / mod_base)
114		sub_low = sub_low % mod_base
115
116		tab_base_low = sub_low - tab_base_low;
117		tab_base_high = sub_high - tab_base_high;
118		tab_base_sign = -1;
119		if (tab_base_low < 0) {
120			tab_base_low = tab_base_low + mod_base
121			tab_base_high--
122		}
123	}
124	print "/*" > outfile
125	print " * " outfn ":" > outfile
126	print " * This file is automatically generated; please do not edit it." > outfile
127	print " */" > outfile
128
129	print "" > outfile
130	print "#include <stdlib.h>" > outfile
131	print "" > outfile
132	print "static const char * const text[] = {" > outfile
133	table_item_count = 0
134}
135
136(continuation == 1) && ($0 ~ /\\[ \t]*$/) {
137	text=substr($0,1,length($0)-1);
138#	printf "\t\t\"%s\"\n", text > outfile
139	cont_buf=cont_buf text;
140}
141
142(continuation == 1) && ($0 ~ /"[ \t]*$/) {
143#	printf "\t\t\"%s,\n", $0 > outfile
144	printf "\t%s,\n", cont_buf $0 > outfile
145	continuation = 0;
146}
147
148/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[^ \t]/ {
149	# Be tolerant to missing whitespace after `,' ...
150	sub(/,/, ", ")
151}
152
153/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*$/ {
154	table_item_count++
155	skipone=1
156	next
157}
158
159/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*".*"[ \t]*$/ {
160	text=""
161	for (i=3; i<=NF; i++) { 
162	    text = text FS $i
163	}
164	text=substr(text,2,length(text)-1);
165	printf "\t%s,\n", text > outfile
166	table_item_count++
167}
168
169/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*".*\\[ \t]*$/ {
170	text=""
171	for (i=3; i<=NF; i++) { 
172	    text = text FS $i
173	}
174	text=substr(text,2,length(text)-2);
175#	printf "\t%s\"\n", text > outfile
176	cont_buf=text
177	table_item_count++
178	continuation++;
179}
180
181/^[ \t]*".*\\[ \t]*$/ {
182	if (skipone) {
183	    text=substr($0,1,length($0)-1);
184#	    printf "\t%s\"\n", text > outfile
185	    cont_buf=text
186	    continuation++;
187	}
188	skipone=0
189}
190
191{ 
192	if (skipone) {
193	    printf "\t%s,\n", $0 > outfile
194	}
195	skipone=0
196}
197
198/^[ \t]*(prefix)$/ {
199	prefix_str = ""
200}
201
202/^[ \t]*(prefix)[ \t]+[A-Z_0-9]+/ {
203	prefix_str = $2 "_"
204}
205
206/^[ \t]*(index)[ \t]+[A-Z_0-9]+/ {
207	new_idx = $2
208	for (i = table_item_count ; i < new_idx; i++) {
209		printf "\t\"Reserved %s error (%d)\",\n", \
210			table_name, table_item_count++ > outfile
211	}
212}
213
214END {
215	print "    0" > outfile
216	print "};" > outfile
217	print "" > outfile
218	print "struct error_table {" > outfile
219	print "    char const * const * msgs;" > outfile
220	print "    long base;" > outfile
221	print "    int n_msgs;" > outfile
222	print "};" > outfile
223	print "struct et_list {" > outfile
224	print "    struct et_list *next;" > outfile
225	print "    const struct error_table * table;" > outfile
226	print "};" > outfile
227	print "extern struct et_list *_et_list;" > outfile
228	print "" > outfile
229	if (tab_base_high == 0) {
230		print "const struct error_table et_" table_name "_error_table = { text, " \
231		sprintf("%dL, %d };", tab_base_sign*tab_base_low, \
232		table_item_count) > outfile
233	} else {
234		print "const struct error_table et_" table_name "_error_table = { text, " \
235		sprintf("%d%06dL, %d };", tab_base_sign*tab_base_high, \
236		tab_base_low, table_item_count) > outfile
237	}
238	print "" > outfile
239	print "static struct et_list link = { 0, 0 };" > outfile
240	print "" > outfile
241	print "void initialize_" table_name "_error_table_r(struct et_list **list);" > outfile
242	print "void initialize_" table_name "_error_table(void);" > outfile
243	print "" > outfile
244	print "void initialize_" table_name "_error_table(void) {" > outfile
245	print "    initialize_" table_name "_error_table_r(&_et_list);" > outfile
246	print "}" > outfile
247	print "" > outfile
248	print "/* For Heimdal compatibility */" > outfile
249	print "void initialize_" table_name "_error_table_r(struct et_list **list)" > outfile
250	print "{" > outfile
251	print "    struct et_list *et, **end;" > outfile
252	print "" > outfile
253	print "    for (end = list, et = *list; et; end = &et->next, et = et->next)" > outfile
254	print "        if (et->table->msgs == text)" > outfile
255	print "            return;" > outfile
256	print "    et = malloc(sizeof(struct et_list));" > outfile
257	print "    if (et == 0) {" > outfile
258	print "        if (!link.table)" > outfile
259	print "            et = &link;" > outfile
260	print "        else" > outfile
261	print "            return;" > outfile
262	print "    }" > outfile
263	print "    et->table = &et_" table_name "_error_table;" > outfile
264	print "    et->next = 0;" > outfile
265	print "    *end = et;" > outfile
266	print "}" > outfile
267}
268