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 * 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 * 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 * 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 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 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 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 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 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