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: error_table.y 3956 2010-01-05 20:56:56Z zacheiss $"; |
---|
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 | } |
---|