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