version 1.2, 1998/05/13 17:54:21 |
version 1.3, 2000/02/19 12:07:19 |
|
|
%{ |
%{ |
/* $OpenBSD$ */ |
/* |
|
* Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan |
/*- |
* (Royal Institute of Technology, Stockholm, Sweden). |
* Copyright 1987, 1988 by the Student Information Processing Board |
* All rights reserved. |
* of the Massachusetts Institute of Technology |
|
* |
* |
* Permission to use, copy, modify, and distribute this software |
* Redistribution and use in source and binary forms, with or without |
* and its documentation for any purpose and without fee is |
* modification, are permitted provided that the following conditions |
* hereby granted, provided that the above copyright notice |
* are met: |
* appear in all copies and that both that copyright notice and |
* |
* this permission notice appear in supporting documentation, |
* 1. Redistributions of source code must retain the above copyright |
* and that the names of M.I.T. and the M.I.T. S.I.P.B. not be |
* notice, this list of conditions and the following disclaimer. |
* used in advertising or publicity pertaining to distribution |
* |
* of the software without specific, written prior permission. |
* 2. Redistributions in binary form must reproduce the above copyright |
* M.I.T. and the M.I.T. S.I.P.B. make no representations about |
* notice, this list of conditions and the following disclaimer in the |
* the suitability of this software for any purpose. It is |
* documentation and/or other materials provided with the distribution. |
* provided "as is" without express or implied warranty. |
* |
|
* 3. All advertising materials mentioning features or use of this software |
|
* must display the following acknowledgement: |
|
* This product includes software developed by Kungliga Tekniska |
|
* Högskolan and its contributors. |
|
* |
|
* 4. Neither the name of the Institute nor the names of its contributors |
|
* may be used to endorse or promote products derived from this software |
|
* without specific prior written permission. |
|
* |
|
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
* SUCH DAMAGE. |
*/ |
*/ |
|
|
#include <stdio.h> |
#include "compile_et.h" |
#include <stdlib.h> |
/* RCSID("$KTH: parse.y,v 1.9 1999/07/04 14:54:58 assar Exp $"); */ |
char *str_concat(), *ds(), *quote(); |
|
char *current_token = (char *)NULL; |
void yyerror (char *s); |
extern char *table_name; |
long name2number(const char *str); |
|
void error_message(char *, ...); |
|
|
|
extern char *yytext; |
|
|
|
/* This is for bison */ |
|
|
|
#if !defined(alloca) && !defined(HAVE_ALLOCA) |
|
#define alloca(x) malloc(x) |
|
#endif |
|
|
%} |
%} |
|
|
%union { |
%union { |
char *dynstr; |
char *string; |
|
int number; |
} |
} |
|
|
%token ERROR_TABLE ERROR_CODE_ENTRY END |
%token ET INDEX PREFIX EC ID END |
%token <dynstr> STRING QUOTED_STRING |
%token <string> STRING |
%type <dynstr> ec_name description table_id |
%token <number> NUMBER |
%{ |
|
%} |
|
%start error_table |
|
%% |
%% |
|
|
error_table : ERROR_TABLE table_id error_codes END |
file : /* */ |
{ table_name = ds($2); |
| header statements |
current_token = table_name; |
|
put_ecs(); } |
|
; |
; |
|
|
table_id : STRING |
header : id et |
{ current_token = $1; |
| et |
set_table_num($1); |
|
$$ = $1; } |
|
; |
; |
|
|
error_codes : error_codes ec_entry |
id : ID STRING |
| ec_entry |
{ |
|
id_str = $2; |
|
} |
; |
; |
|
|
ec_entry : ERROR_CODE_ENTRY ec_name ',' description |
et : ET STRING |
{ add_ec($2, $4); |
{ |
free($2); |
base = name2number($2); |
free($4); } |
strncpy(name, $2, sizeof(name)); |
| ERROR_CODE_ENTRY ec_name '=' STRING ',' description |
name[sizeof(name) - 1] = '\0'; |
{ add_ec_val($2, $4, $6); |
free($2); |
free($2); |
} |
free($4); |
| ET STRING STRING |
free($6); |
{ |
} |
base = name2number($2); |
|
strncpy(name, $3, sizeof(name)); |
|
name[sizeof(name) - 1] = '\0'; |
|
free($2); |
|
free($3); |
|
} |
; |
; |
|
|
ec_name : STRING |
statements : statement |
{ $$ = ds($1); |
| statements statement |
current_token = $$; } |
|
; |
; |
|
|
description : QUOTED_STRING |
statement : INDEX NUMBER |
{ $$ = ds($1); |
{ |
current_token = $$; } |
number = $2; |
|
} |
|
| PREFIX STRING |
|
{ |
|
prefix = realloc(prefix, strlen($2) + 2); |
|
strcpy(prefix, $2); |
|
strcat(prefix, "_"); |
|
free($2); |
|
} |
|
| PREFIX |
|
{ |
|
prefix = realloc(prefix, 1); |
|
*prefix = '\0'; |
|
} |
|
| EC STRING ',' STRING |
|
{ |
|
struct error_code *ec = malloc(sizeof(*ec)); |
|
|
|
ec->next = NULL; |
|
ec->number = number; |
|
if(prefix && *prefix != '\0') { |
|
asprintf (&ec->name, "%s%s", prefix, $2); |
|
free($2); |
|
} else |
|
ec->name = $2; |
|
ec->string = $4; |
|
APPEND(codes, ec); |
|
number++; |
|
} |
|
| END |
|
{ |
|
YYACCEPT; |
|
} |
; |
; |
|
|
%% |
%% |
/* |
|
* Copyright 1987, 1988 by the Student Information Processing Board |
|
* of the Massachusetts Institute of Technology |
|
* |
|
* Permission to use, copy, modify, and distribute this software |
|
* and its documentation for any purpose and without fee is |
|
* hereby granted, provided that the above copyright notice |
|
* appear in all copies and that both that copyright notice and |
|
* this permission notice appear in supporting documentation, |
|
* and that the names of M.I.T. and the M.I.T. S.I.P.B. not be |
|
* used in advertising or publicity pertaining to distribution |
|
* of the software without specific, written prior permission. |
|
* M.I.T. and the M.I.T. S.I.P.B. make no representations about |
|
* the suitability of this software for any purpose. It is |
|
* provided "as is" without express or implied warranty. |
|
*/ |
|
|
|
#include <string.h> |
long |
#include <assert.h> |
name2number(const char *str) |
#include <ctype.h> |
|
#include <sys/types.h> |
|
#include <sys/time.h> |
|
#include "error_table.h" |
|
|
|
#ifndef lint |
|
static char const rcsid_error_table_y[] = |
|
"$Id$"; |
|
#endif |
|
|
|
#include "et_lex.lex.c" |
|
|
|
extern FILE *hfile, *cfile; |
|
|
|
static long gensym_n = 0; |
|
char * |
|
gensym(x) |
|
char const *x; |
|
{ |
{ |
char *symbol; |
const char *p; |
if (!gensym_n) { |
long base = 0; |
struct timeval tv; |
const char *x = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
struct timezone tzp; |
"abcdefghijklmnopqrstuvwxyz0123456789_"; |
gettimeofday(&tv, &tzp); |
if(strlen(str) > 4) { |
gensym_n = (tv.tv_sec%10000)*100 + tv.tv_usec/10000; |
yyerror("table name too long"); |
|
return 0; |
|
} |
|
for(p = str; *p; p++){ |
|
char *q = strchr(x, *p); |
|
if(q == NULL) { |
|
yyerror("invalid character in table name"); |
|
return 0; |
} |
} |
symbol = (char *)malloc(32 * sizeof(char)); |
base = (base << 6) + (q - x) + 1; |
gensym_n++; |
} |
snprintf(symbol, 32 * sizeof(char), "et%ld", gensym_n); |
base <<= 8; |
return(symbol); |
if(base > 0x7fffffff) |
|
base = -(0xffffffff - base + 1); |
|
return base; |
} |
} |
|
|
char * |
|
ds(string) |
|
char const *string; |
|
{ |
|
char *rv; |
|
rv = (char *)malloc(strlen(string)+1); |
|
strcpy(rv, string); |
|
return(rv); |
|
} |
|
|
|
char * |
|
quote(string) |
|
char const *string; |
|
{ |
|
char *rv; |
|
rv = (char *)malloc(strlen(string)+3); |
|
strcpy(rv, "\""); |
|
strcat(rv, string); |
|
strcat(rv, "\""); |
|
return(rv); |
|
} |
|
|
|
int table_number; |
|
int current = 0; |
|
char **error_codes = (char **)NULL; |
|
|
|
void |
void |
add_ec(name, description) |
yyerror (char *s) |
char const *name, *description; |
|
{ |
{ |
fprintf(cfile, "\t\"%s\",\n", description); |
error_message ("%s\n", s); |
if (error_codes == (char **)NULL) { |
|
error_codes = (char **)malloc(sizeof(char *)); |
|
*error_codes = (char *)NULL; |
|
} |
|
error_codes = (char **)realloc((char *)error_codes, |
|
(current + 2)*sizeof(char *)); |
|
error_codes[current++] = ds(name); |
|
error_codes[current] = (char *)NULL; |
|
} |
} |
|
|
void |
|
add_ec_val(name, val, description) |
|
char const *name, *val, *description; |
|
{ |
|
const int ncurrent = atoi(val); |
|
if (ncurrent < current) { |
|
printf("Error code %s (%d) out of order", name, |
|
current); |
|
return; |
|
} |
|
|
|
while (ncurrent > current) |
|
fputs("\t(char *)NULL,\n", cfile), current++; |
|
|
|
fprintf(cfile, "\t\"%s\",\n", description); |
|
if (error_codes == (char **)NULL) { |
|
error_codes = (char **)malloc(sizeof(char *)); |
|
*error_codes = (char *)NULL; |
|
} |
|
error_codes = (char **)realloc((char *)error_codes, |
|
(current + 2)*sizeof(char *)); |
|
error_codes[current++] = ds(name); |
|
error_codes[current] = (char *)NULL; |
|
} |
|
|
|
void |
|
put_ecs() |
|
{ |
|
int i; |
|
for (i = 0; i < current; i++) { |
|
if (error_codes[i] != (char *)NULL) |
|
fprintf(hfile, "#define %-40s (%d)\n", |
|
error_codes[i], table_number + i); |
|
} |
|
} |
|
|
|
/* |
|
* char_to_num -- maps letters and numbers into a small numbering space |
|
* uppercase -> 1-26 |
|
* lowercase -> 27-52 |
|
* digits -> 53-62 |
|
* underscore-> 63 |
|
*/ |
|
|
|
static const char char_set[] = |
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; |
|
|
|
int char_to_num(c) |
|
char c; |
|
{ |
|
const char *where; |
|
int diff; |
|
|
|
where = strchr (char_set, c); |
|
if (where) { |
|
diff = where - char_set + 1; |
|
assert (diff < (1 << ERRCODE_RANGE)); |
|
return diff; |
|
} |
|
else if (isprint (c)) |
|
fprintf (stderr, |
|
"Illegal character `%c' in error table name\n", |
|
c); |
|
else |
|
fprintf (stderr, |
|
"Illegal character %03o in error table name\n", |
|
c); |
|
exit (1); |
|
} |
|
|
|
void |
|
set_table_num(string) |
|
char *string; |
|
{ |
|
if (char_to_num (string[0]) > char_to_num ('z')) { |
|
fprintf (stderr, "%s%s%s%s", |
|
"First character of error table name must be ", |
|
"a letter; name ``", |
|
string, "'' rejected\n"); |
|
exit (1); |
|
} |
|
if (strlen(string) > 4) { |
|
fprintf(stderr, "Table name %s too long, truncated ", |
|
string); |
|
string[4] = '\0'; |
|
fprintf(stderr, "to %s\n", string); |
|
} |
|
while (*string != '\0') { |
|
table_number = (table_number << BITS_PER_CHAR) |
|
+ char_to_num(*string); |
|
string++; |
|
} |
|
table_number = table_number << ERRCODE_RANGE; |
|
} |
|
|
|