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 "#define N_(a) a" > outfile
133	print "" > outfile
134	print "static const char * const text[] = {" > outfile
135	table_item_count = 0
136}
137
138(continuation == 1) && ($0 ~ /\\[ \t]*$/) {
139	text=substr($0,1,length($0)-1);
140#	printf "\t\t\"%s\"\n", text > outfile
141	cont_buf=cont_buf text;
142}
143
144(continuation == 1) && ($0 ~ /"[ \t]*$/) {
145#	printf "\t\t\"%s,\n", $0 > outfile
146	printf "\tN_(%s),\n", cont_buf $0 > outfile
147	continuation = 0;
148}
149
150/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[^ \t]/ {
151	# Be tolerant to missing whitespace after `,' ...
152	sub(/,/, ", ")
153}
154
155/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*$/ {
156	table_item_count++
157	skipone=1
158	next
159}
160
161/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*".*"[ \t]*$/ {
162	text=""
163	for (i=3; i<=NF; i++) {
164	    text = text FS $i
165	}
166	text=substr(text,2,length(text)-1);
167	printf "\tN_(%s),\n", text > outfile
168	table_item_count++
169}
170
171/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*".*\\[ \t]*$/ {
172	text=""
173	for (i=3; i<=NF; i++) {
174	    text = text FS $i
175	}
176	text=substr(text,2,length(text)-2);
177#	printf "\t%s\"\n", text > outfile
178	cont_buf=text
179	table_item_count++
180	continuation++;
181}
182
183/^[ \t]*".*\\[ \t]*$/ {
184	if (skipone) {
185	    text=substr($0,1,length($0)-1);
186#	    printf "\t%s\"\n", text > outfile
187	    cont_buf=text
188	    continuation++;
189	}
190	skipone=0
191}
192
193{
194	if (skipone) {
195	    printf "\tN_(%s),\n", $0 > outfile
196	}
197	skipone=0
198}
199
200/^[ \t]*(prefix)$/ {
201	prefix_str = ""
202}
203
204/^[ \t]*(prefix)[ \t]+[A-Z_0-9]+/ {
205	prefix_str = $2 "_"
206}
207
208/^[ \t]*(index)[ \t]+[A-Z_0-9]+/ {
209	new_idx = $2
210	for (i = table_item_count ; i < new_idx; i++) {
211		printf "\tN_(\"Reserved %s error (%d)\"),\n", \
212			table_name, table_item_count++ > outfile
213	}
214}
215
216END {
217	print "    0" > outfile
218	print "};" > outfile
219	print "" > outfile
220	print "struct error_table {" > outfile
221	print "    char const * const * msgs;" > outfile
222	print "    long base;" > outfile
223	print "    int n_msgs;" > outfile
224	print "};" > outfile
225	print "struct et_list {" > outfile
226	print "    struct et_list *next;" > outfile
227	print "    const struct error_table * table;" > outfile
228	print "};" > outfile
229	print "extern struct et_list *_et_list;" > outfile
230	print "" > outfile
231	if (tab_base_high == 0) {
232		print "const struct error_table et_" table_name "_error_table = { text, " \
233		sprintf("%dL, %d };", tab_base_sign*tab_base_low, \
234		table_item_count) > outfile
235	} else {
236		print "const struct error_table et_" table_name "_error_table = { text, " \
237		sprintf("%d%06dL, %d };", tab_base_sign*tab_base_high, \
238		tab_base_low, table_item_count) > outfile
239	}
240	print "" > outfile
241	print "static struct et_list link = { 0, 0 };" > outfile
242	print "" > outfile
243	print "void initialize_" table_name "_error_table_r(struct et_list **list);" > outfile
244	print "void initialize_" table_name "_error_table(void);" > outfile
245	print "" > outfile
246	print "void initialize_" table_name "_error_table(void) {" > outfile
247	print "    initialize_" table_name "_error_table_r(&_et_list);" > outfile
248	print "}" > outfile
249	print "" > outfile
250	print "/* For Heimdal compatibility */" > outfile
251	print "void initialize_" table_name "_error_table_r(struct et_list **list)" > outfile
252	print "{" > outfile
253	print "    struct et_list *et, **end;" > outfile
254	print "" > outfile
255	print "    for (end = list, et = *list; et; end = &et->next, et = et->next)" > outfile
256	print "        if (et->table->msgs == text)" > outfile
257	print "            return;" > outfile
258	print "    et = malloc(sizeof(struct et_list));" > outfile
259	print "    if (et == 0) {" > outfile
260	print "        if (!link.table)" > outfile
261	print "            et = &link;" > outfile
262	print "        else" > outfile
263	print "            return;" > outfile
264	print "    }" > outfile
265	print "    et->table = &et_" table_name "_error_table;" > outfile
266	print "    et->next = 0;" > outfile
267	print "    *end = et;" > outfile
268	print "}" > outfile
269}
270