source: trunk/third/moira/util/et/error_table.y @ 24319

Revision 24319, 4.5 KB checked in by broder, 15 years ago (diff)
New Moira snapshot from SVN.
Line 
1%{
2#include <stdio.h>
3#include <stdlib.h>
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);
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
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
88static const char rcsid[] = "$Id: error_table.y 3956 2010-01-05 20:56:56Z zacheiss $";
89
90#include "et_lex.lex.c"
91
92extern FILE *hfile, *cfile;
93
94char *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
110static 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
119long table_number;
120int current = 0;
121char **error_codes = NULL;
122
123static 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
135static 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
159static 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
177static const char char_set[] =
178        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
179
180static 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
202static 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}
Note: See TracBrowser for help on using the repository browser.