xref: /freebsd/crypto/heimdal/lib/com_err/parse.y (revision 1669d8afc64812c8d2d1d147ae1fd42ff441e1b1)
1 %{
2 /*
3  * Copyright (c) 1998 - 2000 Kungliga Tekniska H�gskolan
4  * (Royal Institute of Technology, Stockholm, Sweden).
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the Institute nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 #include "compile_et.h"
36 #include "lex.h"
37 
38 RCSID("$Id: parse.y,v 1.11 2000/06/22 00:42:52 assar Exp $");
39 
40 void yyerror (char *s);
41 static long name2number(const char *str);
42 
43 extern char *yytext;
44 
45 /* This is for bison */
46 
47 #if !defined(alloca) && !defined(HAVE_ALLOCA)
48 #define alloca(x) malloc(x)
49 #endif
50 
51 %}
52 
53 %union {
54   char *string;
55   int number;
56 }
57 
58 %token ET INDEX PREFIX EC ID END
59 %token <string> STRING
60 %token <number> NUMBER
61 
62 %%
63 
64 file		: /* */
65 		| header statements
66 		;
67 
68 header		: id et
69 		| et
70 		;
71 
72 id		: ID STRING
73 		{
74 		    id_str = $2;
75 		}
76 		;
77 
78 et		: ET STRING
79 		{
80 		    base = name2number($2);
81 		    strncpy(name, $2, sizeof(name));
82 		    name[sizeof(name) - 1] = '\0';
83 		    free($2);
84 		}
85 		| ET STRING STRING
86 		{
87 		    base = name2number($2);
88 		    strncpy(name, $3, sizeof(name));
89 		    name[sizeof(name) - 1] = '\0';
90 		    free($2);
91 		    free($3);
92 		}
93 		;
94 
95 statements	: statement
96 		| statements statement
97 		;
98 
99 statement	: INDEX NUMBER
100 		{
101 			number = $2;
102 		}
103 		| PREFIX STRING
104 		{
105 		    prefix = realloc(prefix, strlen($2) + 2);
106 		    strcpy(prefix, $2);
107 		    strcat(prefix, "_");
108 		    free($2);
109 		}
110 		| PREFIX
111 		{
112 		    prefix = realloc(prefix, 1);
113 		    *prefix = '\0';
114 		}
115 		| EC STRING ',' STRING
116 		{
117 		    struct error_code *ec = malloc(sizeof(*ec));
118 
119 		    ec->next = NULL;
120 		    ec->number = number;
121 		    if(prefix && *prefix != '\0') {
122 			asprintf (&ec->name, "%s%s", prefix, $2);
123 			free($2);
124 		    } else
125 			ec->name = $2;
126 		    ec->string = $4;
127 		    APPEND(codes, ec);
128 		    number++;
129 		}
130 		| END
131 		{
132 			YYACCEPT;
133 		}
134 		;
135 
136 %%
137 
138 static long
139 name2number(const char *str)
140 {
141     const char *p;
142     long base = 0;
143     const char *x = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
144 	"abcdefghijklmnopqrstuvwxyz0123456789_";
145     if(strlen(str) > 4) {
146 	yyerror("table name too long");
147 	return 0;
148     }
149     for(p = str; *p; p++){
150 	char *q = strchr(x, *p);
151 	if(q == NULL) {
152 	    yyerror("invalid character in table name");
153 	    return 0;
154 	}
155 	base = (base << 6) + (q - x) + 1;
156     }
157     base <<= 8;
158     if(base > 0x7fffffff)
159 	base = -(0xffffffff - base + 1);
160     return base;
161 }
162 
163 void
164 yyerror (char *s)
165 {
166      error_message ("%s\n", s);
167 }
168