/ lib / com_err / parse.y
parse.y
  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_et.h"
 37  
 38  void yyerror (char *s);
 39  static long name2number(const char *str);
 40  
 41  extern char *yytext;
 42  
 43  /* This is for bison */
 44  
 45  #if !defined(alloca) && !defined(HAVE_ALLOCA)
 46  #define alloca(x) malloc(x)
 47  #endif
 48  
 49  #define YYMALLOC malloc
 50  #define YYFREE free
 51  
 52  %}
 53  
 54  %union {
 55    char *string;
 56    int number;
 57  }
 58  
 59  %token ET INDEX PREFIX CFPREFIX EC ID END
 60  %token <string> STRING
 61  %token <number> NUMBER
 62  
 63  %%
 64  
 65  file		: /* */
 66  		| header statements
 67  		;
 68  
 69  header		: id et
 70  		| et
 71  		;
 72  
 73  id		: ID STRING
 74  		{
 75  		    id_str = $2;
 76  		}
 77  		;
 78  
 79  et		: ET STRING
 80  		{
 81  		    base_id = name2number($2);
 82  		    strlcpy(name, $2, sizeof(name));
 83  		    free($2);
 84  		}
 85  		| ET STRING STRING
 86  		{
 87  		    base_id = name2number($2);
 88  		    strlcpy(name, $3, sizeof(name));
 89  		    free($2);
 90  		    free($3);
 91  		}
 92  		;
 93  
 94  statements	: statement
 95  		| statements statement
 96  		;
 97  
 98  statement	: INDEX NUMBER
 99  		{
100  			number = $2;
101  		}
102  		| CFPREFIX STRING
103  		{
104  		    prefix = $2;
105  		}
106  		| PREFIX STRING
107  		{
108  		    free(prefix);
109  		    asprintf (&prefix, "%s_", $2);
110  		    if (prefix == NULL)
111  			errx(1, "malloc");
112  		    free($2);
113  		}
114  		| PREFIX
115  		{
116  		    prefix = realloc(prefix, 1);
117  		    if (prefix == NULL)
118  			errx(1, "malloc");
119  		    *prefix = '\0';
120  		}
121  		| EC STRING ',' STRING
122  		{
123  		    struct error_code *ec = malloc(sizeof(*ec));
124  
125  		    if (ec == NULL)
126  			errx(1, "malloc");
127  
128  		    ec->next = NULL;
129  		    ec->number = number;
130  		    if(prefix && *prefix != '\0') {
131  			asprintf (&ec->name, "%s%s", prefix, $2);
132  			if (ec->name == NULL)
133  			    errx(1, "malloc");
134  			free($2);
135  		    } else
136  			ec->name = $2;
137  		    ec->string = $4;
138  		    APPEND(codes, ec);
139  		    number++;
140  		}
141  		| END
142  		{
143  			YYACCEPT;
144  		}
145  		;
146  
147  %%
148  
149  static long
150  name2number(const char *str)
151  {
152      const char *p;
153      long num = 0;
154      const char *x = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
155  	"abcdefghijklmnopqrstuvwxyz0123456789_";
156      if(strlen(str) > 4) {
157  	yyerror("table name too long");
158  	return 0;
159      }
160      for(p = str; *p; p++){
161  	char *q = strchr(x, *p);
162  	if(q == NULL) {
163  	    yyerror("invalid character in table name");
164  	    return 0;
165  	}
166  	num = (num << 6) + (q - x) + 1;
167      }
168      num <<= 8;
169      if(num > 0x7fffffff)
170  	num = -(0xffffffff - num + 1);
171      return num;
172  }
173  
174  void
175  yyerror (char *s)
176  {
177       _lex_error_message ("%s\n", s);
178  }