parse.y revision 19163
16527Sache%{
26527Sache/*-
36527Sache * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
46527Sache *		at Electronni Visti IA, Kiev, Ukraine.
56527Sache *			All rights reserved.
66527Sache *
76527Sache * Redistribution and use in source and binary forms, with or without
86527Sache * modification, are permitted provided that the following conditions
96527Sache * are met:
106527Sache * 1. Redistributions of source code must retain the above copyright
116527Sache *    notice, this list of conditions and the following disclaimer.
126527Sache * 2. Redistributions in binary form must reproduce the above copyright
136527Sache *    notice, this list of conditions and the following disclaimer in the
146527Sache *    documentation and/or other materials provided with the distribution.
156527Sache *
166527Sache * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
176527Sache * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
186527Sache * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
196527Sache * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
206527Sache * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
216527Sache * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
226527Sache * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
236527Sache * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
246527Sache * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
256527Sache * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
266527Sache * SUCH DAMAGE.
276527Sache *
2819163Sache * $Id: parse.y,v 1.4 1996/10/23 14:59:56 ache Exp $
296527Sache */
306527Sache
316527Sache#include <err.h>
3218950Sache#include <stdarg.h>
336527Sache#include <stdio.h>
346527Sache#include <string.h>
356527Sache#include <stdlib.h>
366527Sache#include <sysexits.h>
376527Sache#include "collate.h"
386527Sache
396527Sacheextern int line_no;
406527Sacheextern FILE *yyin;
4118950Sachevoid yyerror(char *fmt, ...);
426527Sache
4318950Sachechar map_name[FILENAME_MAX] = ".";
4418950Sache
4518950Sachechar __collate_version[STR_LEN];
4618950Sacheu_char charmap_table[UCHAR_MAX + 1][STR_LEN];
476527Sacheu_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN];
486527Sachestruct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1];
496527Sachestruct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE];
5018950Sacheint chain_index;
516527Sacheint prim_pri = 1, sec_pri = 1;
526527Sache#ifdef COLLATE_DEBUG
536527Sacheint debug;
546527Sache#endif
556527Sache
566527Sachechar *out_file = "LC_COLLATE";
576527Sache%}
586527Sache%union {
596527Sache	u_char ch;
606527Sache	u_char str[STR_LEN];
616527Sache}
626527Sache%token SUBSTITUTE WITH ORDER RANGE
636527Sache%token <str> STRING
646527Sache%token <str> CHAIN
6518950Sache%token <str> DEFN
666527Sache%token <ch> CHAR
676527Sache%%
686527Sachecollate : statment_list
696527Sache;
706527Sachestatment_list : statment
716527Sache	| statment_list '\n' statment
726527Sache;
736527Sachestatment :
746527Sache	| charmap
756527Sache	| substitute
766527Sache	| order
776527Sache;
7818950Sachecharmap : DEFN CHAR {
7918950Sache	strcpy(charmap_table[$2], $1);
806527Sache}
816527Sache;
826527Sachesubstitute : SUBSTITUTE STRING WITH STRING {
836527Sache	strcpy(__collate_substitute_table[$2[0]], $4);
846527Sache}
856527Sache;
866527Sacheorder : ORDER order_list {
8719128Sache	FILE *fp;
8819128Sache	int ch;
896527Sache
9019128Sache	for (ch = 0; ch < UCHAR_MAX + 1; ch++)
9119128Sache		if (!__collate_char_pri_table[ch].prim)
9219163Sache			yyerror("Char 0x%02x not present", ch);
9319128Sache
9419128Sache	fp = fopen(out_file, "w");
956527Sache	if(!fp)
9618950Sache		err(EX_UNAVAILABLE, "can't open destination file %s",
976527Sache		    out_file);
986527Sache
9918950Sache	strcpy(__collate_version, COLLATE_VERSION);
10018950Sache	fwrite(__collate_version, sizeof(__collate_version), 1, fp);
1016527Sache	fwrite(__collate_substitute_table, sizeof(__collate_substitute_table), 1, fp);
1026527Sache	fwrite(__collate_char_pri_table, sizeof(__collate_char_pri_table), 1, fp);
1036527Sache	fwrite(__collate_chain_pri_table, sizeof(__collate_chain_pri_table), 1, fp);
10418950Sache	if (fflush(fp))
10518950Sache		err(EX_UNAVAILABLE, "IO error writting to destination file %s",
10618950Sache		    out_file);
10718950Sache	fclose(fp);
1086527Sache#ifdef COLLATE_DEBUG
1096527Sache	if (debug)
11019128Sache		collate_print_tables();
1116527Sache#endif
1126527Sache	exit(EX_OK);
1136527Sache}
1146527Sache;
1156527Sacheorder_list : item
1166527Sache	| order_list ';' item
1176527Sache;
11819128Sacheitem :  CHAR {
11919128Sache	if (__collate_char_pri_table[$1].prim)
12019163Sache		yyerror("Char 0x%02x duplicated", $1);
12119128Sache	__collate_char_pri_table[$1].prim = prim_pri++;
12219128Sache}
1236527Sache	| CHAIN {
1246527Sache	if (chain_index >= TABLE_SIZE - 1)
1256527Sache		yyerror("__collate_chain_pri_table overflow");
1266527Sache	strcpy(__collate_chain_pri_table[chain_index].str, $1);
1276527Sache	__collate_chain_pri_table[chain_index++].prim = prim_pri++;
1286527Sache}
1296527Sache	| CHAR RANGE CHAR {
1306527Sache	u_int i;
1316527Sache
1326527Sache	if ($3 <= $1)
13318950Sache		yyerror("Illegal range 0x%02x -- 0x%02x", $1, $3);
1346527Sache
13519128Sache	for (i = $1; i <= $3; i++) {
13619128Sache		if (__collate_char_pri_table[(u_char)i].prim)
13719163Sache			yyerror("Char 0x%02x duplicated", (u_char)i);
1386527Sache		__collate_char_pri_table[(u_char)i].prim = prim_pri++;
13919128Sache	}
1406527Sache}
1416527Sache	| '{' prim_order_list '}' {
1426527Sache	prim_pri++;
1436527Sache}
1446527Sache	| '(' sec_order_list ')' {
1456527Sache	prim_pri++;
1466527Sache	sec_pri = 1;
1476527Sache}
1486527Sache;
1496527Sacheprim_order_list : prim_sub_item
1506527Sache	| prim_order_list ',' prim_sub_item
1516527Sache;
1526527Sachesec_order_list : sec_sub_item
1536527Sache	| sec_order_list ',' sec_sub_item
1546527Sache;
1556527Sacheprim_sub_item : CHAR {
15619128Sache	if (__collate_char_pri_table[$1].prim)
15719163Sache		yyerror("Char 0x%02x duplicated", $1);
1586527Sache	__collate_char_pri_table[$1].prim = prim_pri;
1596527Sache}
1606527Sache	| CHAR RANGE CHAR {
1616527Sache	u_int i;
1626527Sache
1636527Sache	if ($3 <= $1)
16418950Sache		yyerror("Illegal range 0x%02x -- 0x%02x",
16518950Sache			$1, $3);
1666527Sache
16719128Sache	for (i = $1; i <= $3; i++) {
16819128Sache		if (__collate_char_pri_table[(u_char)i].prim)
16919163Sache			yyerror("Char 0x%02x duplicated", (u_char)i);
1706527Sache		__collate_char_pri_table[(u_char)i].prim = prim_pri;
17119128Sache	}
1726527Sache}
1736527Sache	| CHAIN {
1746527Sache	if (chain_index >= TABLE_SIZE - 1)
1756527Sache		yyerror("__collate_chain_pri_table overflow");
1766527Sache	strcpy(__collate_chain_pri_table[chain_index].str, $1);
1776527Sache	__collate_chain_pri_table[chain_index++].prim = prim_pri;
1786527Sache}
1796527Sache;
1806527Sachesec_sub_item : CHAR {
18119128Sache	if (__collate_char_pri_table[$1].prim)
18219163Sache		yyerror("Char 0x%02x duplicated", $1);
1836527Sache	__collate_char_pri_table[$1].prim = prim_pri;
1846527Sache	__collate_char_pri_table[$1].sec = sec_pri++;
1856527Sache}
1866527Sache	| CHAR RANGE CHAR {
1876527Sache	u_int i;
1886527Sache
1896527Sache	if ($3 <= $1)
19018950Sache		yyerror("Illegal range 0x%02x -- 0x%02x",
19118950Sache			$1, $3);
1926527Sache
1936527Sache	for (i = $1; i <= $3; i++) {
19419128Sache		if (__collate_char_pri_table[(u_char)i].prim)
19519163Sache			yyerror("Char 0x%02x duplicated", (u_char)i);
1966527Sache		__collate_char_pri_table[(u_char)i].prim = prim_pri;
1976527Sache		__collate_char_pri_table[(u_char)i].sec = sec_pri++;
1986527Sache	}
1996527Sache}
2006527Sache	| CHAIN {
2016527Sache	if (chain_index >= TABLE_SIZE - 1)
2026527Sache		yyerror("__collate_chain_pri_table overflow");
2036527Sache	strcpy(__collate_chain_pri_table[chain_index].str, $1);
2046527Sache	__collate_chain_pri_table[chain_index].prim = prim_pri;
2056527Sache	__collate_chain_pri_table[chain_index++].sec = sec_pri++;
2066527Sache}
2076527Sache;
2086527Sache%%
2096527Sachemain(ac, av)
2106527Sache	char **av;
2116527Sache{
2126527Sache	int ch;
2136527Sache
2146527Sache#ifdef COLLATE_DEBUG
21518950Sache	while((ch = getopt(ac, av, ":do:I:")) != EOF) {
2166527Sache#else
21718950Sache	while((ch = getopt(ac, av, ":o:I:")) != EOF) {
2186527Sache#endif
2196527Sache		switch (ch)
2206527Sache		{
2216527Sache#ifdef COLLATE_DEBUG
2226527Sache		  case 'd':
2236527Sache			debug++;
2246527Sache			break;
2256527Sache#endif
2266527Sache		  case 'o':
2276527Sache			out_file = optarg;
2286527Sache			break;
2296527Sache
23018950Sache		  case 'I':
23118950Sache			strcpy(map_name, optarg);
23218950Sache			break;
23318950Sache
2346527Sache		  default:
23518950Sache			fprintf(stderr, "Usage: %s [-o out_file] [-I map_dir] [in_file]\n",
2366527Sache				av[0]);
2376527Sache			exit(EX_OK);
2386527Sache		}
2396527Sache	}
2406527Sache	ac -= optind;
2416527Sache	av += optind;
2426527Sache	if(ac > 0) {
2436527Sache		if((yyin = fopen(*av, "r")) == 0)
2446527Sache			err(EX_UNAVAILABLE, "can't open source file %s", *av);
2456527Sache	}
2466527Sache	for(ch = 0; ch <= UCHAR_MAX; ch++)
2476527Sache		__collate_substitute_table[ch][0] = ch;
2486527Sache	yyparse();
2496527Sache	return 0;
2506527Sache}
2516527Sache
25218950Sachevoid yyerror(char *fmt, ...)
2536527Sache{
25418950Sache	va_list ap;
25518950Sache	char msg[128];
25618950Sache
25718950Sache	va_start(ap, fmt);
25818950Sache	vsprintf(msg, fmt, ap);
25918950Sache	va_end(ap);
2606527Sache	errx(EX_UNAVAILABLE, "%s near line %d", msg, line_no);
2616527Sache}
26219128Sache
26319128Sache#ifdef COLLATE_DEBUG
26419128Sachecollate_print_tables()
26519128Sache{
26619128Sache	int i;
26719128Sache	struct __collate_st_chain_pri *p2;
26819128Sache
26919128Sache	printf("Substitute table:\n");
27019128Sache	for (i = 0; i < UCHAR_MAX + 1; i++)
27119128Sache	    if (i != *__collate_substitute_table[i])
27219128Sache		printf("\t'%c' --> \"%s\"\n", i,
27319128Sache		       __collate_substitute_table[i]);
27419128Sache	printf("Chain priority table:\n");
27519128Sache	for (p2 = __collate_chain_pri_table; p2->str[0]; p2++)
27619128Sache		printf("\t\"%s\" : %d %d\n\n", p2->str, p2->prim, p2->sec);
27719128Sache	printf("Char priority table:\n");
27819128Sache	for (i = 0; i < UCHAR_MAX + 1; i++)
27919128Sache		printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim,
28019128Sache		       __collate_char_pri_table[i].sec);
28119128Sache}
28219128Sache#endif
283