Accept topic changes from servers that do not send topic-set timestamps (fixes SF...
[ircu2.10.12-pk.git] / libs / dbprim / comp_et-sh.in
1 #! /bin/sh
2 #
3 # Copyright (C) 2000 by Kevin L. Mitchell <klmitch@mit.edu>
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 #
19 # @(#)$Id: comp_et-sh.in,v 1.1 2003-03-07 02:36:10 klmitch Exp $
20
21 com_err=true
22 c_file=
23 c_name=
24 c_dir=
25 h_file=
26 h_name=
27 h_dir=
28 dir=
29 in_file=
30
31 ce_prev=
32 for ce_option
33 do
34     # if the previous option needed an argument, assign it...
35     if test -n "$ce_prev"; then
36         eval "$ce_prev=\$ce_option"
37         ce_prev=
38         continue
39     fi
40
41     case "$ce_option" in
42     -*=*) ce_optarg=`echo "$ce_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
43     *) ce_optarg= ;;
44     esac
45
46     case "$ce_option" in
47
48      -c_f   |  -c_fi   |  -c_fil   |  -c_file   | \
49      -c-f   |  -c-fi   |  -c-fil   |  -c-file   | \
50     --c_f   | --c_fi   | --c_fil   | --c_file   | \
51     --c-f   | --c-fi   | --c-fil   | --c-file   )
52         ce_prev=c_file ;;
53      -c_f=* |  -c_fi=* |  -c_fil=* |  -c_file=* | \
54      -c-f=* |  -c-fi=* |  -c-fil=* |  -c-file=* | \
55     --c_f=* | --c_fi=* | --c_fil=* | --c_file=* | \
56     --c-f=* | --c-fi=* | --c-fil=* | --c-file=* )
57         c_file="$ce_optarg" ;;
58
59      -c_d   |  -c_di   |  -c_dir   | \
60      -c-d   |  -c-di   |  -c-dir   | \
61     --c_d   | --c_di   | --c_dir   | \
62     --c-d   | --c-di   | --c-dir   )
63         ce_prev=c_dir ;;
64      -c_d=* |  -c_di=* |  -c_dir=* | \
65      -c-d=* |  -c-di=* |  -c-dir=* | \
66     --c_d=* | --c_di=* | --c_dir=* | \
67     --c-d=* | --c-di=* | --c-dir=* )
68         c_dir="$ce_optarg" ;;
69
70      -h_f   |  -h_fi   |  -h_fil   |  -h_file   | \
71      -h-f   |  -h-fi   |  -h-fil   |  -h-file   | \
72     --h_f   | --h_fi   | --h_fil   | --h_file   | \
73     --h-f   | --h-fi   | --h-fil   | --h-file   )
74         ce_prev=h_file ;;
75      -h_f=* |  -h_fi=* |  -h_fil=* |  -h_file=* | \
76      -h-f=* |  -h-fi=* |  -h-fil=* |  -h-file=* | \
77     --h_f=* | --h_fi=* | --h_fil=* | --h_file=* | \
78     --h-f=* | --h-fi=* | --h-fil=* | --h-file=* )
79         h_file="$ce_optarg" ;;
80
81      -h_d   |  -h_di   |  -h_dir   | \
82      -h-d   |  -h-di   |  -h-dir   | \
83     --h_d   | --h_di   | --h_dir   | \
84     --h-d   | --h-di   | --h-dir   )
85         ce_prev=h_dir ;;           
86      -h_d=* |  -h_di=* |  -h_dir=* | \
87      -h-d=* |  -h-di=* |  -h-dir=* | \
88     --h_d=* | --h_di=* | --h_dir=* | \
89     --h-d=* | --h-di=* | --h-dir=* )
90         h_dir="$ce_optarg" ;;
91
92      -d   |  -di   |  -dir   | \
93     --d   | --di   | --dir   )
94         ce_prev=dir ;;
95      -d=* |  -di=* |  -dir=* | \
96     --d=* | --di=* | --dir=* )
97         dir="$ce_optarg" ;;
98
99      -com   |  -com_   |  -com_e   |  -com_er   |  -com_err   | \
100                -com-   |  -com-e   |  -com-er   |  -com-err   | \
101     --com   | --com_   | --com_e   | --com_er   | --com_err   | \
102               --com-   | --com-e   | --com-er   | --com-err   )
103         ce_prev=com_err ;;
104      -com=* |  -com_=* |  -com_e=* |  -com_er=* |  -com_err=* | \
105                -com-=* |  -com-e=* |  -com-er=* |  -com-err=* | \
106     --com=* | --com_=* | --com_e=* | --com_er=* | --com_err=* | \
107               --com-=* | --com-e=* | --com-er=* | --com-err=* )
108         com_err="$ce_optarg" ;;
109
110      -he |  -hel |  -help | \
111     --he | --hel | --help )
112         cat <<EOF
113 Usage: $0 [options] <infile>
114 Options:
115   --c-file=FILE              Set the output .c file to FILE
116   --h-file=FILE              Set the output .h file to FILE
117   --com-err=OPTION           Selects whether support for com_err should be
118                              used; OPTION may be either true or false
119   --help                     Print this message
120 EOF
121         exit 0 ;;
122
123     -*)
124         echo "$0: Invalid option $ce_option; use --help to show usage" 1>&2
125         exit 1 ;;
126
127     *)
128         if test -n "$in_file"; then
129             echo "$0: Can only process one file at a time" 1>&2
130             exit 1
131         fi
132         in_file="$ce_option" ;;
133     esac
134 done
135
136 if test -n "$ce_prev"; then
137     echo "$0: Missing argument for option; use --help to show usage" 1>&2
138     exit 1
139 fi
140
141 if test -z "$in_file"; then
142     echo "$0: No input file specified; use --help to show usage" 1>&2
143     exit 1
144 fi
145
146 if test ! -r "$in_file"; then
147     echo "$0: Unable to read input file $in_file" 1>&2
148     exit 1
149 fi
150
151 com_err=`echo "$com_err" | tr 'A-Z' 'a-z'`
152
153 case "$com_err" in
154 t | tr | tru | true | y | ye | yes)
155     com_err=true ;;
156
157 f | fa | fal | fals | false | n | no)
158     com_err=false ;;
159
160 *)
161     echo "$0: Invalid value for --com-err; use --help to show usage" 1>&2
162     exit 1 ;;
163 esac
164
165 in_dir=`echo "$in_file" | sed 's%/[^/]*$%%'`
166 in_name=`echo "$in_file" | sed -e 's%.*/%%' -e 's/\.et$//'`
167
168 if test -z "$dir"; then
169     dir="$in_dir"
170 fi
171
172 if test -z "$c_dir"; then
173     c_dir="$dir"
174 fi
175
176 if test -z "$h_dir"; then
177     h_dir="$dir"
178 fi
179
180 if test "$com_err" = false; then
181     c_file="/dev/null"
182     c_dir=
183 elif test -z "$c_file"; then
184     c_file="$c_dir/$in_name.c"
185 fi
186
187 c_name=`echo "$c_file" | sed 's%.*/%%'`
188
189 if test -z "$h_file"; then
190     h_file="$h_dir/$in_name.h"
191 fi
192
193 h_name=`echo "$h_file" | sed 's%.*/%%'`
194
195 @AWK@ -f - "com_err=$com_err" "c_file=$c_file" "c_name=$c_name" \
196                             "h_file=$h_file" "h_name=$h_name" "$in_file" <<\EOF
197 BEGIN {
198     char_shift = 64;
199
200     c2n["A"] = 1;   c2n["B"] = 2;   c2n["C"] = 3;   c2n["D"] = 4;
201     c2n["E"] = 5;   c2n["F"] = 6;   c2n["G"] = 7;   c2n["H"] = 8;
202     c2n["I"] = 9;   c2n["J"] = 10;  c2n["K"] = 11;  c2n["L"] = 12;
203     c2n["M"] = 13;  c2n["N"] = 14;  c2n["O"] = 15;  c2n["P"] = 16;
204     c2n["Q"] = 17;  c2n["R"] = 18;  c2n["S"] = 19;  c2n["T"] = 20;
205     c2n["U"] = 21;  c2n["V"] = 22;  c2n["W"] = 23;  c2n["X"] = 24;
206     c2n["Y"] = 25;  c2n["Z"] = 26;  c2n["a"] = 27;  c2n["b"] = 28;
207     c2n["c"] = 29;  c2n["d"] = 30;  c2n["e"] = 31;  c2n["f"] = 32;
208     c2n["g"] = 33;  c2n["h"] = 34;  c2n["i"] = 35;  c2n["j"] = 36;
209     c2n["k"] = 37;  c2n["l"] = 38;  c2n["m"] = 39;  c2n["n"] = 40;
210     c2n["o"] = 41;  c2n["p"] = 42;  c2n["q"] = 43;  c2n["r"] = 44;
211     c2n["s"] = 45;  c2n["t"] = 46;  c2n["u"] = 47;  c2n["v"] = 48;
212     c2n["w"] = 49;  c2n["x"] = 50;  c2n["y"] = 51;  c2n["z"] = 52;
213     c2n["0"] = 53;  c2n["1"] = 54;  c2n["2"] = 55;  c2n["3"] = 56;
214     c2n["4"] = 57;  c2n["5"] = 58;  c2n["6"] = 59;  c2n["7"] = 60;
215     c2n["8"] = 61;  c2n["9"] = 62;  c2n["_"] = 63;
216 }
217
218 /^#/ { next }
219
220 /^[ \t]*(error_table|et)[ \t]+[a-zA-Z][a-zA-Z0-9_]+/ {
221     tab_num = 0;
222     tab_name = $2;
223     mod_base = 1000000;
224
225     for (i = 1; i <= length(tab_name); i++) {
226         tab_num = (tab_num * char_shift) + c2n[substr(tab_name, i, 1)];
227     }
228
229     # Some awk programs don't have enough precision, so we have to play
230     # some games here...
231     base_low = tab_num % mod_base;
232     base_high = int(tab_num / mod_base);
233     base_sign = 1;
234
235     # now shift it over by 8 bits...
236     base_low = base_low * 256;
237     base_high = (base_high * 256) + int(base_low / mod_base);
238     base_low = base_low % mod_base;
239
240     # Next, figure out the sign...
241     if (tab_num > (128 * 256 * 256)) {
242         # subtract 256 * 256 * 256 * 256...
243         sub_low = 256 * 256 * 256 % mod_base;
244         sub_high = int(256 * 256 * 256 / mod_base);
245
246         sub_low = sub_low * 256;
247         sub_high = (sub_high * 256) + int(sub_low / mod_base);
248         sub_low = sub_low % mod_base;
249
250         base_low = sub_low - base_low;
251         base_high = sub_high - base_high;
252         base_sign = -1;
253         # Now correct for base_low being negative...
254         if (base_low < 0) {
255             base_low = base_low + mod_base;
256             base_high--;
257         }
258     }
259
260     curr_low = base_low;
261     curr_high = base_high;
262     curr_sign = base_sign;
263
264     tab_count = 0;
265
266     print "/*" > h_file;
267     print " * " h_name ":" > h_file;
268     print " * This file is automatically generated; please do not edit it." > h_file;
269     print " */" > h_file;
270
271     print "/*" > c_file;
272     print " * " c_name ":" > c_file;
273     print " * This file is automatically generated; please do not edit it." > c_file;
274     print " */" > c_file;
275     print "#if defined(__STDC__) || defined(_MSDOS) || defined(_WIN32)" > c_file;
276     print "#define NOARGS void" > c_file;
277     print "#else" > c_file;
278     print "#define NOARGS" > c_file;
279     print "#define const" > c_file;
280     print "#endif" > c_file;
281     print "" > c_file;
282     print "static const char * const text[] = {" > c_file;
283 }
284
285 (cont == 1) && ($0 ~ /\\[ \t]*$/) {
286     text = substr($0, 1, length($0) - 1);
287     cont_buf = cont_buf text;
288 }
289
290 (cont == 1) && ($0 ~ /"[ \t]*$/) {
291     printf "\t%s,\n", cont_buf $0 > c_file;
292     cont = 0;
293 }
294
295 /^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*$/ {
296     tag = substr($2, 1, length($2) - 1);
297     if (curr_high == 0) {
298         printf "#define %-40s (%dL)\n", tag, curr_sign * curr_low > h_file;
299     } else {
300         printf "#define %-40s (%d%06dL)\n", tag, curr_sign * curr_high , curr_low > h_file;
301     }
302     curr_low += curr_sign;
303     if (curr_low >= mod_base) {
304         curr_low -= mod_base;
305         curr_high++;
306     }
307     if (curr_low < 0) {
308         curr_low += mod_base;
309         curr_high--;
310     }
311
312     tab_count++;
313     skipone = 1;
314     next;
315 }
316
317 /^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*".*"[ \t]*$/ {
318     tag = substr($2, 1, length($2) - 1);
319     if (curr_high == 0) {
320         printf "#define %-40s (%dL)\n", tag, curr_sign * curr_low > h_file;
321     } else {
322         printf "#define %-40s (%d%06dL)\n", tag, curr_sign * curr_high , curr_low > h_file;
323     }
324     curr_low += curr_sign;
325     if (curr_low >= mod_base) {
326         curr_low -= mod_base;
327         curr_high++;
328     }
329     if (curr_low < 0) {
330         curr_low += mod_base;
331         curr_high--;
332     }
333
334     text = "";
335     for (i = 3; i <= NF; i++) {
336         text = text FS $i;
337     }
338
339     text = substr(text, 2, length(text) - 1);
340     printf "\t%s,\n", text > c_file;
341     tab_count++;
342 }
343
344 /^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*".*\\[ \t]*$/ {
345     tag = substr($2, 1, length($2) - 1);
346     if (curr_high == 0) {
347         printf "#define %-40s (%dL)\n", tag, curr_sign * curr_low > h_file;
348     } else {
349         printf "#define %-40s (%d%06dL)\n", tag, curr_sign * curr_high , curr_low > h_file;
350     }
351     curr_low += curr_sign;
352     if (curr_low >= mod_base) {
353         curr_low -= mod_base;
354         curr_high++;
355     }
356     if (curr_low < 0) {
357         curr_low += mod_base;
358         curr_high--;
359     }
360
361     text = "";
362     for (i = 3; i <= NF; i++) {
363         text = text FS $i;
364     }
365
366     text = substr(text, 2, length(text) - 2);
367     cont_buf = text;
368     cont++;
369 }
370
371 /^[ \t]*".*\\[ \t]*$/ {
372     if (skipone) {
373         text = substr($0, 1, length($0) - 1);
374         cont_buf = text;
375         cont++;
376     }
377     skipone = 0;
378 }
379
380 {
381     if (skipone) {
382         printf "\t%s,\n", $0 > c_file;
383     }
384     skipone = 0;
385 }
386
387 END {
388     if (com_err == "false") {
389         print "#define initialize_" tab_name "_error_table()" > h_file;
390     } else {
391         print "extern void initialize_" tab_name "_error_table ();" > h_file;
392     }
393
394     if (base_high == 0) {
395         printf "#define ERROR_TABLE_BASE_%s (%dL)\n", tab_name, base_sign * base_low > h_file;
396     } else {
397         printf "#define ERROR_TABLE_BASE_%s (%d%06dL)\n", tab_name, base_sign * base_high, base_low > h_file;
398     }
399     print "" > h_file;
400     print "/* for compatibility with older versions... */" > h_file;
401     print "#define init_" tab_name "_err_tbl initialize_" tab_name "_error_table" > h_file;
402     print "#define " tab_name "_err_base ERROR_TABLE_BASE_" tab_name > h_file;
403
404     print "    0" > c_file;
405     print "};" > c_file;
406     print "" > c_file;
407     print "struct error_table {" > c_file;
408     print "    char const * const * msgs;" > c_file;
409     print "    long base;" > c_file;
410     print "    int n_msgs;" > c_file;
411     print "};" > c_file;
412     print "struct et_list {" > c_file;
413     print "    struct et_list *next;" > c_file;
414     print "    const struct error_table * table;" > c_file;
415     print "};" > c_file;
416     print "extern struct et_list *_et_list;" > c_file;
417     print "" > c_file;
418     if (base_high == 0) {
419         printf "static const struct error_table et = { text, %dL, %d };\n", base_sign * base_low, tab_count > c_file;
420     } else {
421         printf "static const struct error_table et = { text, %d%06dL, %d };\n", base_sign * base_high, base_low, tab_count > c_file;
422     }
423     print "" > c_file;
424     print "static struct et_list link = { 0, 0 };" > c_file;
425     print "" > c_file;
426     print "void initialize_" tab_name "_error_table (NOARGS) {" > c_file;
427     print "    if (!link.table) {" > c_file;
428     print "        link.next = _et_list;" > c_file;
429     print "        link.table = &et;" > c_file;
430     print "        _et_list = &link;" > c_file;
431     print "    }" > c_file;
432     print "}"> c_file;
433 }
434 EOF