]> andersk Git - moira.git/blame - util/et/error_table.y
include stdlib.h to make Irix 6.5 happy
[moira.git] / util / et / error_table.y
CommitLineData
d1b2a10e 1%{
2#include <stdio.h>
42775dd9 3#include <stdlib.h>
a91a6d50 4
5char *gensym(const char *x);
6static char *ds(const char *string);
7static void add_ec(const char *name, const char *description);
8static void add_ec_val(const char *name, const char *val,
9 const char *description);
10static void put_ecs(void);
11static int char_to_num(char c);
12static void set_table_num(char *string);
13
14static long gensym_n = 0;
15
16char *current_token = NULL;
17
18extern int yyerror(char *s);
d1b2a10e 19extern 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
33error_table : ERROR_TABLE table_id error_codes END
34 { table_name = ds($2);
35 current_token = table_name;
36 put_ecs(); }
37 ;
38
39table_id : STRING
40 { current_token = $1;
41 set_table_num($1);
42 $$ = $1; }
43 ;
44
45error_codes : error_codes ec_entry
46 | ec_entry
47 ;
48
49ec_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
61ec_name : STRING
62 { $$ = ds($1);
63 current_token = $$; }
64 ;
65
66description : 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
a91a6d50 79#include "mit-sipb-copyright.h"
80
d1b2a10e 81#include <string.h>
82#include <assert.h>
83#include <ctype.h>
84#include <sys/types.h>
85#include <sys/time.h>
d1b2a10e 86#include "error_table.h"
d1b2a10e 87
a91a6d50 88static const char rcsid[] = "$Id$";
89
90#include "et_lex.lex.c"
d1b2a10e 91
d1b2a10e 92extern FILE *hfile, *cfile;
93
a91a6d50 94char *gensym(const char *x)
d1b2a10e 95{
96 char *symbol;
a91a6d50 97
d1b2a10e 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
a91a6d50 110static char *ds(const char *string)
d1b2a10e 111{
112 char *rv;
a91a6d50 113
d1b2a10e 114 rv = malloc(strlen(string)+1);
115 strcpy(rv, string);
116 return(rv);
117}
118
d1b2a10e 119long table_number;
120int current = 0;
a91a6d50 121char **error_codes = NULL;
d1b2a10e 122
a91a6d50 123static void add_ec(const char *name, const char *description)
d1b2a10e 124{
125 fprintf(cfile, "\t\"%s\",\n", description);
a91a6d50 126 if (error_codes == NULL) {
127 error_codes = malloc(sizeof(char *));
128 *error_codes = NULL;
d1b2a10e 129 }
a91a6d50 130 error_codes = realloc(error_codes, (current + 2) * sizeof(char *));
d1b2a10e 131 error_codes[current++] = ds(name);
a91a6d50 132 error_codes[current] = NULL;
d1b2a10e 133}
134
a91a6d50 135static void add_ec_val(const char *name, const char *val,
136 const char *description)
d1b2a10e 137{
138 const int ncurrent = atoi(val);
a91a6d50 139
d1b2a10e 140 if (ncurrent < current) {
141 printf("Error code %s (%d) out of order", name,
142 current);
143 return;
144 }
145
146 while (ncurrent > current)
a91a6d50 147 fputs("\tNULL,\n", cfile), current++;
d1b2a10e 148
149 fprintf(cfile, "\t\"%s\",\n", description);
a91a6d50 150 if (error_codes == NULL) {
151 error_codes = malloc(sizeof(char *));
152 *error_codes = NULL;
d1b2a10e 153 }
a91a6d50 154 error_codes = realloc(error_codes, (current + 2) * sizeof(char *));
d1b2a10e 155 error_codes[current++] = ds(name);
a91a6d50 156 error_codes[current] = NULL;
d1b2a10e 157}
158
a91a6d50 159static void put_ecs(void)
d1b2a10e 160{
161 int i;
162 for (i = 0; i < current; i++) {
a91a6d50 163 if (error_codes[i] != NULL)
d1b2a10e 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
177static const char char_set[] =
178 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
179
a91a6d50 180static int char_to_num(char c)
d1b2a10e 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
a91a6d50 202static void set_table_num(char *string)
d1b2a10e 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.089305 seconds and 5 git commands to generate.