]> andersk Git - moira.git/blob - util/et/error_table.y
include stdlib.h to make Irix 6.5 happy
[moira.git] / util / et / error_table.y
1 %{
2 #include <stdio.h>
3 #include <stdlib.h>
4
5 char *gensym(const char *x);
6 static char *ds(const char *string);
7 static void add_ec(const char *name, const char *description);
8 static void add_ec_val(const char *name, const char *val,
9                        const char *description);
10 static void put_ecs(void);
11 static int char_to_num(char c);
12 static void set_table_num(char *string);
13
14 static long gensym_n = 0;
15
16 char *current_token = NULL;
17
18 extern int yyerror(char *s);
19 extern char *table_name;
20 %}
21 %union {
22         char *dynstr;
23 }
24
25 %token ERROR_TABLE ERROR_CODE_ENTRY END
26 %token <dynstr> STRING QUOTED_STRING
27 %type <dynstr> ec_name description table_id
28 %{
29 %}
30 %start error_table
31 %%
32
33 error_table     :       ERROR_TABLE table_id error_codes END
34                         { table_name = ds($2);
35                           current_token = table_name;
36                           put_ecs(); }
37                 ;
38
39 table_id        :       STRING
40                         { current_token = $1;
41                           set_table_num($1);
42                           $$ = $1; }
43                 ;
44
45 error_codes     :       error_codes ec_entry
46                 |       ec_entry
47                 ;
48
49 ec_entry        :       ERROR_CODE_ENTRY ec_name ',' description
50                         { add_ec($2, $4);
51                           free($2);
52                           free($4); }
53                 |       ERROR_CODE_ENTRY ec_name '=' STRING ',' description
54                         { add_ec_val($2, $4, $6);
55                           free($2);
56                           free($4);
57                           free($6);
58                         }
59                 ;
60
61 ec_name         :       STRING
62                         { $$ = ds($1);
63                           current_token = $$; }
64                 ;
65
66 description     :       QUOTED_STRING
67                         { $$ = ds($1);
68                           current_token = $$; }
69                 ;
70
71 %%
72 /*
73  *
74  * Copyright 1986, 1987 by the MIT Student Information Processing Board
75  *
76  * For copyright info, see mit-sipb-copyright.h.
77  */
78
79 #include "mit-sipb-copyright.h"
80
81 #include <string.h>
82 #include <assert.h>
83 #include <ctype.h>
84 #include <sys/types.h>
85 #include <sys/time.h>
86 #include "error_table.h"
87
88 static const char rcsid[] = "$Id$";
89
90 #include "et_lex.lex.c"
91
92 extern FILE *hfile, *cfile;
93
94 char *gensym(const char *x)
95 {
96         char *symbol;
97
98         if (!gensym_n) {
99                 struct timeval tv;
100                 struct timezone tzp;
101                 gettimeofday(&tv, &tzp);
102                 gensym_n = (tv.tv_sec%10000)*100 + tv.tv_usec/10000;
103         }
104         symbol = malloc(32 * sizeof(char));
105         gensym_n++;
106         sprintf(symbol, "et%ld", gensym_n);
107         return(symbol);
108 }
109
110 static char *ds(const char *string)
111 {
112         char *rv;
113
114         rv = malloc(strlen(string)+1);
115         strcpy(rv, string);
116         return(rv);
117 }
118
119 long table_number;
120 int current = 0;
121 char **error_codes = NULL;
122
123 static void add_ec(const char *name, const char *description)
124 {
125         fprintf(cfile, "\t\"%s\",\n", description);
126         if (error_codes == NULL) {
127                 error_codes = malloc(sizeof(char *));
128                 *error_codes = NULL;
129         }
130         error_codes = realloc(error_codes, (current + 2) * sizeof(char *));
131         error_codes[current++] = ds(name);
132         error_codes[current] = NULL;
133 }
134
135 static void add_ec_val(const char *name, const char *val,
136                        const char *description)
137 {
138         const int ncurrent = atoi(val);
139
140         if (ncurrent < current) {
141                 printf("Error code %s (%d) out of order", name,
142                        current);
143                 return;
144         }
145       
146         while (ncurrent > current)
147              fputs("\tNULL,\n", cfile), current++;
148         
149         fprintf(cfile, "\t\"%s\",\n", description);
150         if (error_codes == NULL) {
151                 error_codes = malloc(sizeof(char *));
152                 *error_codes = NULL;
153         }
154         error_codes = realloc(error_codes, (current + 2) * sizeof(char *));
155         error_codes[current++] = ds(name);
156         error_codes[current] = NULL;
157
158
159 static void put_ecs(void)
160 {
161         int i;
162         for (i = 0; i < current; i++) {
163              if (error_codes[i] != NULL)
164                   fprintf(hfile, "#define %-40s (%ldL)\n",
165                           error_codes[i], table_number + i);
166         }
167 }
168
169 /*
170  * char_to_num -- maps letters and numbers into a small numbering space
171  *      uppercase ->  1-26
172  *      lowercase -> 27-52
173  *      digits    -> 53-62
174  *      underscore-> 63
175  */
176
177 static const char char_set[] =
178         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
179
180 static int char_to_num(char c)
181 {
182         const char *where;
183         int diff;
184
185         where = strchr (char_set, c);
186         if (where) {
187                 diff = where - char_set + 1;
188                 assert (diff < (1 << ERRCODE_RANGE));
189                 return diff;
190         }
191         else if (isprint (c))
192                 fprintf (stderr,
193                          "Illegal character `%c' in error table name\n",
194                          c);
195         else
196                 fprintf (stderr,
197                          "Illegal character %03o in error table name\n",
198                          c);
199         exit (1);
200 }
201
202 static void set_table_num(char *string)
203 {
204         if (char_to_num (string[0]) > char_to_num ('z')) {
205                 fprintf (stderr, "%s%s%s%s",
206                          "First character of error table name must be ",
207                          "a letter; name ``",
208                          string, "'' rejected\n");
209                 exit (1);
210         }
211         if (strlen(string) > 4) {
212                 fprintf(stderr, "Table name %s too long, truncated ",
213                         string);
214                 string[4] = '\0';
215                 fprintf(stderr, "to %s\n", string);
216         }
217         while (*string != '\0') {
218                 table_number = (table_number << BITS_PER_CHAR)
219                         + char_to_num(*string);
220                 string++;
221         }
222         table_number = table_number << ERRCODE_RANGE;
223 }
This page took 0.054358 seconds and 5 git commands to generate.