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