Author: Bleep <tomh@inxpress.net>
[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
45 #include "ircd_chattr.h"
46 #include <stdlib.h>
47 #include <stdio.h>
48 #include <ctype.h>
49
50
51 static void zeroTables(void);
52 static void markString(int macro, const char *s);
53 static void unMarkString(int macro, const char *s);
54 static void markRange(int macro, char from, char to);
55 static void moveMacro(int from, int to);
56 static void setLowHi(const char firstlow, const char lastlow,
57     const char firsthi);
58
59 char NTL_tolower_tab[1 + CHAR_MAX - CHAR_MIN];  /* 256 bytes */
60 char NTL_toupper_tab[1 + CHAR_MAX - CHAR_MIN];  /* 256 bytes */
61 int NTL_char_attrib[1 + CHAR_MAX - CHAR_MIN];   /* 256 ints = 0.5 to 2 kilobytes */
62
63 /*
64  * makeTables() 
65  * Where we make the tables, edit ONLY this to change the tables.
66  */
67
68 static void makeTables(void)
69 {
70
71   /* Start from a known status */
72   zeroTables();
73
74   /* Make the very elementary sets */
75   markRange(NTL_LOWER, 'a', 'z');
76   markString(NTL_LOWER, "{|}~");
77
78   markRange(NTL_UPPER, 'A', 'Z');
79   markString(NTL_UPPER, "[\\]^");
80
81   markRange(NTL_DIGIT, '0', '9');
82
83   markRange(NTL_CNTRL, '\000', '\037');
84
85   markString(NTL_PUNCT, "!\"#$%&'()*+,-./:;<=>?@_`");
86
87   markString(NTL_SPACE, "\011\012\013\014\015\040");
88
89   /* Make the derived sets, 
90    * WARNING: The order of these calls is important, some depend on 
91    * the results of the previous ones ! */
92
93   moveMacro(NTL_LOWER | NTL_UPPER, NTL_ALPHA);
94   moveMacro(NTL_ALPHA | NTL_DIGIT, NTL_ALNUM);
95   moveMacro(NTL_ALNUM | NTL_PUNCT, NTL_GRAPH);
96
97   moveMacro(NTL_GRAPH, NTL_PRINT);
98   markString(NTL_PRINT, " ");
99
100   markRange(NTL_IRCCH, 0, UCHAR_MAX);
101   unMarkString(NTL_IRCCH, "\007\040\054\240");
102
103   markRange(NTL_IRCCL, '\300', '\326');
104   markRange(NTL_IRCCL, '\330', '\336');
105
106   moveMacro(NTL_ALNUM, NTL_IRCHN);
107   markString(NTL_IRCHN, "-_."); /* Some DNS might allow '_' per RFC 1033 ! */
108
109   moveMacro(NTL_DIGIT, NTL_IRCIP);
110   markString(NTL_IRCIP, ".");
111
112   moveMacro(NTL_DIGIT | NTL_ALPHA, NTL_IRCNK);
113   markString(NTL_IRCNK, "-_`");
114
115   moveMacro(NTL_ALNUM, NTL_IRCUI);
116   markRange(NTL_IRCUI, '\xe0', '\xf6');
117   markRange(NTL_IRCUI, '\xf8', '\xfe');
118   markRange(NTL_IRCUI, '\xc0', '\xd6');
119   markRange(NTL_IRCUI, '\xd8', '\xde');
120   markString(NTL_IRCUI, ".-_^'`~");
121   markString(NTL_EOL, "\n\r");
122   markString(NTL_CHPFX, "#&+");
123   markString(NTL_KTIME, " ,-0123456789");
124
125   /* And finally let's take care of the toLower/toUpper stuff */
126
127   setLowHi('a', 'z', 'A');
128   setLowHi('\xe0', '\xf6', '\xc0');
129   setLowHi('\xf8', '\xfe', '\xd8');
130   setLowHi('{', '~', '[');
131 }
132
133 /* 
134  * main()
135  * This is the main program to be executed for -DMAKETABLES
136  */
137
138 static void dumphw(int *p, int beg);
139 static void dumphb(char *p, int beg);
140
141 int main(void)
142 {
143   int i;
144
145   /* Make the tables */
146   makeTables();
147
148   /* Dump them as ANSI C source to be included below */
149   printf("/*\n * Automatically Generated Tables - DO NOT EDIT\n */\n");
150   printf("#include <limits.h>\n");
151
152   /* NTL_tolower_tab */
153   printf("const char ToLowerTab_8859_1[] = {\n");
154   printf("#if (CHAR_MIN<0)\n");
155   i = (int)((char)SCHAR_MIN);
156   dumphb(NTL_tolower_tab, i);
157   printf("                ,\n");
158   printf("#endif /* (CHAR_MIN<0) */\n");
159   i = 0;
160   dumphb(NTL_tolower_tab, i);
161   printf("#if (!(CHAR_MIN<0))\n");
162   printf("                ,\n");
163   i = (int)((char)SCHAR_MIN);
164   dumphb(NTL_tolower_tab, i);
165   printf("#endif /* (!(CHAR_MIN<0)) */\n");
166   printf("  };\n\n");
167
168   /* NTL_toupper_tab */
169   printf("const char ToUpperTab_8859_1[] = {\n");
170   printf("#if (CHAR_MIN<0)\n");
171   i = (int)((char)SCHAR_MIN);
172   dumphb(NTL_toupper_tab, i);
173   printf("                ,\n");
174   printf("#endif /* (CHAR_MIN<0) */\n");
175   i = 0;
176   dumphb(NTL_toupper_tab, i);
177   printf("#if (!(CHAR_MIN<0))\n");
178   printf("                ,\n");
179   i = (int)((char)SCHAR_MIN);
180   dumphb(NTL_toupper_tab, i);
181   printf("#endif /* (!(CHAR_MIN<0)) */\n");
182   printf("  };\n\n");
183
184   /* NTL_char_attrib */
185   printf("const unsigned int IRCD_CharAttrTab[] = {\n");
186   printf("#if (CHAR_MIN<0)\n");
187   i = (int)((char)SCHAR_MIN);
188   dumphw(NTL_char_attrib, i);
189   printf("                ,\n");
190   printf("#endif /* (CHAR_MIN<0) */\n");
191   i = 0;
192   dumphw(NTL_char_attrib, i);
193   printf("#if (!(CHAR_MIN<0))\n");
194   printf("                ,\n");
195   i = (int)((char)SCHAR_MIN);
196   dumphw(NTL_char_attrib, i);
197   printf("#endif /* (!(CHAR_MIN<0)) */\n");
198   printf("  };\n\n");
199
200   return 0;
201
202 }
203
204 /* A few utility functions for makeTables() */
205
206 static void zeroTables(void)
207 {
208   int i;
209   for (i = CHAR_MIN; i <= CHAR_MAX; i++)
210   {
211     NTL_tolower_tab[i - CHAR_MIN] = (char)i;    /* Unchanged */
212     NTL_toupper_tab[i - CHAR_MIN] = (char)i;    /* Unchanged */
213     NTL_char_attrib[i - CHAR_MIN] = 0x0000;     /* Nothing */
214   }
215 }
216
217 static void markString(int macro, const char *s)
218 {
219   while (*s)
220     NTL_char_attrib[*(s++) - CHAR_MIN] |= macro;
221 }
222
223 static void unMarkString(int macro, const char *s)
224 {
225   while (*s)
226     NTL_char_attrib[*(s++) - CHAR_MIN] &= ~macro;
227 }
228
229 static void markRange(int macro, char from, char to)
230 {
231   int i;
232   for (i = CHAR_MIN; i <= CHAR_MAX; i++)
233     if (((unsigned char)i >= (unsigned char)from)
234         && ((unsigned char)i <= (unsigned char)to))
235       NTL_char_attrib[(char)i - CHAR_MIN] |= macro;
236 }
237
238 static void moveMacro(int from, int to)
239 {
240   int i;
241   for (i = CHAR_MIN; i <= CHAR_MAX; i++)
242     if (NTL_char_attrib[i - CHAR_MIN] & from)
243       NTL_char_attrib[i - CHAR_MIN] |= to;
244 }
245
246 static void setLowHi(const char firstlow, const char lastlow,
247     const char firsthi)
248 {
249   int i, j;
250   for (i = CHAR_MIN; i <= CHAR_MAX; i++)
251     if (((unsigned char)i >= (unsigned char)firstlow)
252         && ((unsigned char)i <= (unsigned char)lastlow))
253     {
254       j = ((int)((char)(i + (int)(firsthi - firstlow))));
255       NTL_tolower_tab[((char)j) - CHAR_MIN] = (char)i;
256       NTL_toupper_tab[((char)i) - CHAR_MIN] = (char)j;
257     }
258 }
259
260 /* These are used in main() to actually dump the tables, each function
261    dumps half table as hex/char constants... */
262
263 #define ROWSIZE 8
264
265 static void dumphb(char *tbl, int beg)
266 {
267   int i, j, k;
268   char *p = &tbl[beg - CHAR_MIN];
269   char c;
270   for (i = 0; i <= SCHAR_MAX; i += ROWSIZE)
271   {
272     k = i + ROWSIZE - 1;
273     if (k > SCHAR_MAX)
274       k = SCHAR_MAX;
275
276     c = (char)(beg + i);
277     printf("/*");
278     if ((c > 0) && (c < SCHAR_MAX) && (isprint(c)) && (c != '\\')
279         && (c != '\''))
280       printf(" '%c'", c);
281     else
282       printf(" x%02x", ((int)((unsigned char)c)));
283
284     c = (char)(beg + k);
285     printf("-");
286     if ((c > 0) && (c < SCHAR_MAX) && (isprint(c)) && (c != '\\')
287         && (c != '\''))
288       printf("'%c'", c);
289     else
290       printf("x%02x", ((int)((unsigned char)c)));
291     printf(" */");
292
293     for (j = i; j <= k; j++)
294     {
295       c = p[j];
296       if ((c > 0) && (c < SCHAR_MAX) && (isprint(c)) && (c != '\\')
297           && (c != '\''))
298         printf("    '%c'", c);
299       else
300         printf(" '\\x%02x'", ((int)((unsigned char)c)));
301       if (j < SCHAR_MAX)
302         printf(",");
303     }
304     printf("\n");
305   }
306 }
307
308 static void dumphw(int *tbl, int beg)
309 {
310   int i, j, k;
311   int *p = &tbl[beg - CHAR_MIN];
312   char c;
313   for (i = 0; i <= SCHAR_MAX; i += ROWSIZE)
314   {
315     k = i + ROWSIZE - 1;
316     if (k > SCHAR_MAX)
317       k = SCHAR_MAX;
318
319     c = (char)(beg + i);
320     printf("/*");
321     if ((c > 0) && (c < SCHAR_MAX) && (isprint(c)) && (c != '\\')
322         && (c != '\''))
323       printf(" '%c'", c);
324     else
325       printf(" x%02x", ((int)((unsigned char)c)));
326
327     c = (char)(beg + k);
328     printf("-");
329     if ((c > 0) && (c < SCHAR_MAX) && (isprint(c)) && (c != '\\')
330         && (c != '\''))
331       printf("'%c'", c);
332     else
333       printf("x%02x", ((int)((unsigned char)c)));
334     printf(" */");
335
336     for (j = i; j <= k; j++)
337     {
338       printf(" 0x%04x", p[j] & 0xffffffff);
339       if (j < SCHAR_MAX)
340         printf(",");
341     }
342     printf("\n");
343   }
344 }
345