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	# We start playing *_high, *low games here because the some
86	# awk programs do not have the necessary precision (sigh)
87	tab_base_low = table_number % mod_base
88	if (tab_base_low < 0) {
89		# Work around stupid bug in the ARM libm
90		tab_base_low = tab_base_low + mod_base
91	}
92	tab_base_high = int(table_number / mod_base)
93	tab_base_sign = 1;
94
95	# figure out: table_number_base=table_number*256
96	tab_base_low = tab_base_low * 256
97	tab_base_high = (tab_base_high * 256) + \
98			int(tab_base_low / mod_base)
99	tab_base_low = tab_base_low % mod_base
100	if (tab_base_low < 0) {
101		# Work around stupid bug in the ARM libm
102		tab_base_low = tab_base_low + mod_base
103	}
104
105	if (table_number > 128*256*256) {
106		# figure out:  table_number_base -= 256*256*256*256
107		# sub_high, sub_low is 256*256*256*256
108		sub_low = 256*256*256 % mod_base
109		sub_high = int(256*256*256 / mod_base)
110
111		sub_low = sub_low * 256
112		sub_high = (sub_high * 256) + int(sub_low / mod_base)
113		sub_low = sub_low % mod_base
114
115		tab_base_low = sub_low - tab_base_low;
116		tab_base_high = sub_high - tab_base_high;
117		tab_base_sign = -1;
118		if (tab_base_low < 0) {
119			tab_base_low = tab_base_low + mod_base
120			tab_base_high--
121		}
122	}
123	prefix_str = ""
124	curr_idx = 0
125	curr_low = tab_base_low
126	curr_high = tab_base_high
127	curr_sign = tab_base_sign
128	print "/*" > outfile
129	print " * " outfn ":" > outfile
130	print " * This file is automatically generated; please do not edit it." > outfile
131	print " */" > outfile
132	print "" > outfile
133	print "#include <et/com_err.h>" > outfile
134	print "" > outfile
135}
136
137/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,/ {
138	# Be tolerant to missing whitespace after `,' ...
139	sub(/,/, ", ")
140
141	tag=prefix_str substr($2,1,length($2)-1)
142	if (curr_high == 0) {
143		printf "#define %-40s (%dL)\n", tag, \
144			curr_sign*curr_low > outfile
145	} else {
146		printf "#define %-40s (%d%06dL)\n", tag, curr_high*curr_sign, \
147			curr_low > outfile
148	}
149	curr_low += curr_sign;
150	curr_idx++;
151	if (curr_low >= mod_base) {
152		curr_low -= mod_base;
153		curr_high++
154	}
155	if (curr_low < 0) {
156		cur_low += mod_base
157		cur_high--
158	}
159}
160
161/^[ \t]*(prefix)$/ {
162	prefix_str = ""
163}
164
165/^[ \t]*(prefix)[ \t]+[A-Z_0-9]+/ {
166	prefix_str = $2 "_"
167}
168
169/^[ \t]*(index)[ \t]+[A-Z_0-9]+/ {
170	new_idx = $2
171	curr_low += curr_sign * (new_idx - curr_idx)
172	curr_idx = new_idx
173	if (curr_low >= mod_base) {
174		curr_low -= mod_base;
175		curr_high++
176	}
177	if (curr_low < 0) {
178		cur_low += mod_base
179		cur_high--
180	}
181}
182
183
184END {
185	print "extern const struct error_table et_" table_name "_error_table;" > outfile
186	print "extern void initialize_" table_name "_error_table(void);" > outfile
187	print "" > outfile
188	print "/* For compatibility with Heimdal */" > outfile
189	print "extern void initialize_" table_name "_error_table_r(struct et_list **list);" > outfile
190	print "" > outfile
191	if (tab_base_high == 0) {
192		print "#define ERROR_TABLE_BASE_" table_name " (" \
193			sprintf("%d", tab_base_sign*tab_base_low) \
194			"L)" > outfile
195	} else {
196		print "#define ERROR_TABLE_BASE_" table_name " (" \
197			sprintf("%d%06d", tab_base_sign*tab_base_high, \
198			tab_base_low) "L)" > outfile
199	}
200	print "" > outfile
201	print "/* for compatibility with older versions... */" > outfile
202	print "#define init_" table_name "_err_tbl initialize_" table_name "_error_table" > outfile
203	print "#define " table_name "_err_base ERROR_TABLE_BASE_" table_name > outfile
204}
205