Fixes to improve portability (especially to OS X, Solaris, OpenBSD).
[ircu2.10.12-pk.git] / ircd / table_gen.c
1 /*
2  * IRC - Internet Relay Chat, include/common.c
3  * Copyright (C) 1998 Andrea Cocito
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 1, or (at your option)
8  * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20 /*
21  * TABLE GENERATOR
22  * The following part of code is NOT included in the actual server's
23  * or library source, it's just used to build the above tables
24  *
25  * This should rebuild the actual tables and automatically place them
26  * into this source file, note that this part of code is for developers
27  * only, it's supposed to work on both signed and unsigned chars but I
28  * actually tested it only on signed-char architectures, the code and
29  * macros actually used by the server instead DO work and have been tested
30  * on platforms where0 char is both signed or unsigned, this is true as long
31  * as the <limits.h> macros are set properly and without any need to rebuild
32  * the tables (wich as said an admin should NEVER do, tables need to be rebuilt
33  * only when one wants to really change the results or when one has to
34  * compile on architectures where a char is NOT eight bits [?!], yes
35  * it all is supposed to work in that case too... but I can't test it
36  * because I've not found a machine in the world where this happes).
37  *
38  * NEVER -f[un]signed-char on gcc since that does NOT fix the named macros
39  * and you end up in a non-ANSI environment where CHAR_MIN and CHAR_MAX
40  * are _not_ the real limits of a default 'char' type. This is true for
41  * both admins and coders.
42  *
43  */
44 #include "config.h"
45
46 #include "ircd_chattr.h"
47 #include <stdlib.h>
48 #include <stdio.h>
49 #include <ctype.h>
50
51
52 static void zeroTables(void);
53 static void markString(int macro, const char *s);
54 static void unMarkString(int macro, const char *s);
55 static void markRange(int macro, char from, char to);
56 static void moveMacro(int from, int to);
57 static void setLowHi(const char firstlow, const char lastlow,
58     const char firsthi);
59
60 char NTL_tolower_tab[1 + CHAR_MAX - CHAR_MIN];  /* 256 bytes */
61 char NTL_toupper_tab[1 + CHAR_MAX - CHAR_MIN];  /* 256 bytes */
62 int NTL_char_attrib[1 + CHAR_MAX - CHAR_MIN];   /* 256 ints = 0.5 to 2 kilobytes */
63
64 /*
65  * makeTables() 
66  * Where we make the tables, edit ONLY this to change the tables.
67  */
68
69 static void makeTables(void)
70 {
71
72   /* Start from a known status */
73   zeroTables();
74
75   /* Make the very elementary sets */
76   markRange(NTL_LOWER, 'a', 'z');
77   markString(NTL_LOWER, "{|}~");
78
79   markRange(NTL_UPPER, 'A', 'Z');
80   markString(NTL_UPPER, "[\\]^");
81
82   markRange(NTL_DIGIT, '0', '9');
83
84   markRange(NTL_CNTRL, '\000', '\037');
85
86   markString(NTL_PUNCT, "!\"#$%&'()*+,-./:;<=>?@_`");
87
88   markString(NTL_SPACE, "\011\012\013\014\015\040");
89
90   /* Make the derived sets, 
91    * WARNING: The order of these calls is important, some depend on 
92    * the results of the previous ones ! */
93
94   moveMacro(NTL_LOWER | NTL_UPPER, NTL_ALPHA);
95   moveMacro(NTL_ALPHA | NTL_DIGIT, NTL_ALNUM);
96   moveMacro(NTL_ALNUM | NTL_PUNCT, NTL_GRAPH);
97
98   moveMacro(NTL_GRAPH, NTL_PRINT);
99   markString(NTL_PRINT, " ");
100
101   markRange(NTL_IRCCH, '\041', (char) UCHAR_MAX);
102   unMarkString(NTL_IRCCH, "\054\240");
103
104   markRange(NTL_IRCCL, '\300', '\326');
105   markRange(NTL_IRCCL, '\330', '\336');
106
107   moveMacro(NTL_ALNUM, NTL_IRCHN);
108   markString(NTL_IRCHN, "-_."); /* Some DNS might allow '_' per RFC 1033 ! */
109
110   moveMacro(NTL_DIGIT, NTL_IRCIP);
111   markString(NTL_IRCIP, ".");
112
113   moveMacro(NTL_DIGIT | NTL_ALPHA, NTL_IRCNK);
114   markString(NTL_IRCNK, "-_`");
115
116   moveMacro(NTL_ALNUM, NTL_IRCUI);
117   markRange(NTL_IRCUI, '\xe0', '\xf6');
118   markRange(NTL_IRCUI, '\xf8', '\xfe');
119   markRange(NTL_IRCUI, '\xc0', '\xd6');
120   markRange(NTL_IRCUI, '\xd8', '\xde');
121   markString(NTL_IRCUI, ".-_^'`~");
122   markString(NTL_EOL, "\n\r");
123   markString(NTL_CHPFX, "#&");
124   markString(NTL_KTIME, " ,-0123456789");
125
126   /* And finally let's take care of the toLower/toUpper stuff */
127
128   setLowHi('a', 'z', 'A');
129   setLowHi('\xe0', '\xf6', '\xc0');
130   setLowHi('\xf8', '\xfe', '\xd8');
131   setLowHi('{', '~', '[');
132 }
133
134 /* 
135  * main()
136  * This is the main program to be executed for -DMAKETABLES
137  */
138
139 static void dumphw(int *p, int beg);
140 static void dumphb(char *p, int beg);
141
142 int main(void)
143 {
144   int i;
145
146   /* Make the tables */
147   makeTables();
148
149   /* Dump them as ANSI C source to be included below */
150   printf("/*\n * Automatically Generated Tables - DO NOT EDIT\n */\n");
151   printf("#include <limits.h>\n");
152
153   /* NTL_tolower_tab */
154   printf("const char ToLowerTab_8859_1[] = {\n");
155   printf("#if (CHAR_MIN<0)\n");
156   i = (int)((char)SCHAR_MIN);
157   dumphb(NTL_tolower_tab, i);
158   printf("                ,\n");
159   printf("#endif /* (CHAR_MIN<0) */\n");
160   i = 0;
161   dumphb(NTL_tolower_tab, i);
162   printf("#if (!(CHAR_MIN<0))\n");
163   printf("                ,\n");
164   i = (int)((char)SCHAR_MIN);
165   dumphb(NTL_tolower_tab, i);
166   printf("#endif /* (!(CHAR_MIN<0)) */\n");
167   printf("  };\n\n");
168
169   /* NTL_toupper_tab */
170   printf("const char ToUpperTab_8859_1[] = {\n");
171   printf("#if (CHAR_MIN<0)\n");
172   i = (int)((char)SCHAR_MIN);
173   dumphb(NTL_toupper_tab, i);
174   printf("                ,\n");
175   printf("#endif /* (CHAR_MIN<0) */\n");
176   i = 0;
177   dumphb(NTL_toupper_tab, i);
178   printf("#if (!(CHAR_MIN<0))\n");
179   printf("                ,\n");
180   i = (int)((char)SCHAR_MIN);
181   dumphb(NTL_toupper_tab, i);
182   printf("#endif /* (!(CHAR_MIN<0)) */\n");
183   printf("  };\n\n");
184
185   /* NTL_char_attrib */
186   printf("const unsigned int IRCD_CharAttrTab[] = {\n");
187   printf("#if (CHAR_MIN<0)\n");
188   i = (int)((char)SCHAR_MIN);
189   dumphw(NTL_char_attrib, i);
190   printf("                ,\n");
191   printf("#endif /* (CHAR_MIN<0) */\n");
192   i = 0;
193   dumphw(NTL_char_attrib, i);
194   printf("#if (!(CHAR_MIN<0))\n");
195   printf("                ,\n");
196   i = (int)((char)SCHAR_MIN);
197   dumphw(NTL_char_attrib, i);
198   printf("#endif /* (!(CHAR_MIN<0)) */\n");
199   printf("  };\n\n");
200
201   return 0;
202
203 }
204
205 /* A few utility functions for makeTables() */
206
207 static void zeroTables(void)
208 {
209   int i;
210   for (i = CHAR_MIN; i <= CHAR_MAX; i++)
211   {
212     NTL_tolower_tab[i - CHAR_MIN] = (char)i;    /* Unchanged */
213     NTL_toupper_tab[i - CHAR_MIN] = (char)i;    /* Unchanged */
214     NTL_char_attrib[i - CHAR_MIN] = 0x0000;     /* Nothing */
215   }
216 }
217
218 static void markString(int macro, const char *s)
219 {
220   while (*s)
221     NTL_char_attrib[*(s++) - CHAR_MIN] |= macro;
222 }
223
224 static void unMarkString(int macro, const char *s)
225 {
226   while (*s)
227     NTL_char_attrib[*(s++) - CHAR_MIN] &= ~macro;
228 }
229
230 static void markRange(int macro, char from, char to)
231 {
232   int i;
233   for (i = CHAR_MIN; i <= CHAR_MAX; i++)
234     if (((unsigned char)i >= (unsigned char)from)
235         && ((unsigned char)i <= (unsigned char)to))
236       NTL_char_attrib[(char)i - CHAR_MIN] |= macro;
237 }
238
239 static void moveMacro(int from, int to)
240 {
241   int i;
242   for (i = CHAR_MIN; i <= CHAR_MAX; i++)
243     if (NTL_char_attrib[i - CHAR_MIN] & from)
244       NTL_char_attrib[i - CHAR_MIN] |= to;
245 }
246
247 static void setLowHi(const char firstlow, const char lastlow,
248     const char firsthi)
249 {
250   int i, j;
251   for (i = CHAR_MIN; i <= CHAR_MAX; i++)
252     if (((unsigned char)i >= (unsigned char)firstlow)
253         && ((unsigned char)i <= (unsigned char)lastlow))
254     {
255       j = ((int)((char)(i + (int)(firsthi - firstlow))));
256       NTL_tolower_tab[((char)j) - CHAR_MIN] = (char)i;
257       NTL_toupper_tab[((char)i) - CHAR_MIN] = (char)j;
258     }
259 }
260
261 /* These are used in main() to actually dump the tables, each function
262    dumps half table as hex/char constants... */
263
264 #define ROWSIZE 8
265
266 static void dumphb(char *tbl, int beg)
267 {
268   int i, j, k;
269   char *p = &tbl[beg - CHAR_MIN];
270   unsigned char c;
271   for (i = 0; i <= SCHAR_MAX; i += ROWSIZE)
272   {
273     k = i + ROWSIZE - 1;
274     if (k > SCHAR_MAX)
275       k = SCHAR_MAX;
276
277     c = (unsigned char)(beg + i);
278     printf("/*");
279     if ((c > 0) && (c < SCHAR_MAX) && (isprint(c)) && (c != '\\')
280         && (c != '\''))
281       printf(" '%c'", c);
282     else
283       printf(" x%02x", ((int)c));
284
285     c = (unsigned char)(beg + k);
286     printf("-");
287     if ((c > 0) && (c < SCHAR_MAX) && (isprint(c)) && (c != '\\')
288         && (c != '\''))
289       printf("'%c'", c);
290     else
291       printf("x%02x", ((int)c));
292     printf(" */");
293
294     for (j = i; j <= k; j++)
295     {
296       c = p[j];
297       if ((c > 0) && (c < SCHAR_MAX) && (isprint(c)) && (c != '\\')
298           && (c != '\''))
299         printf("    '%c'", c);
300       else
301         printf(" '\\x%02x'", ((int)c));
302       if (j < SCHAR_MAX)
303         printf(",");
304     }
305     printf("\n");
306   }
307 }
308
309 static void dumphw(int *tbl, int beg)
310 {
311   int i, j, k;
312   int *p = &tbl[beg - CHAR_MIN];
313   unsigned char c;
314   for (i = 0; i <= SCHAR_MAX; i += ROWSIZE)
315   {
316     k = i + ROWSIZE - 1;
317     if (k > SCHAR_MAX)
318       k = SCHAR_MAX;
319
320     c = (unsigned char)(beg + i);
321     printf("/*");
322     if ((c > 0) && (c < SCHAR_MAX) && (isprint(c)) && (c != '\\')
323         && (c != '\''))
324       printf(" '%c'", c);
325     else
326       printf(" x%02x", ((int)c));
327
328     c = (unsigned char)(beg + k);
329     printf("-");
330     if ((c > 0) && (c < SCHAR_MAX) && (isprint(c)) && (c != '\\')
331         && (c != '\''))
332       printf("'%c'", c);
333     else
334       printf("x%02x", ((int)c));
335     printf(" */");
336
337     for (j = i; j <= k; j++)
338     {
339       printf(" 0x%04x", p[j] & 0xffffffff);
340       if (j < SCHAR_MAX)
341         printf(",");
342     }
343     printf("\n");
344   }
345 }
346