143967Sache%x string name charmap defn nchar subs subs2
26527Sache%{
36527Sache/*-
46527Sache * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
56527Sache *		at Electronni Visti IA, Kiev, Ukraine.
66527Sache *			All rights reserved.
76527Sache *
86527Sache * Redistribution and use in source and binary forms, with or without
96527Sache * modification, are permitted provided that the following conditions
106527Sache * are met:
116527Sache * 1. Redistributions of source code must retain the above copyright
126527Sache *    notice, this list of conditions and the following disclaimer.
136527Sache * 2. Redistributions in binary form must reproduce the above copyright
146527Sache *    notice, this list of conditions and the following disclaimer in the
156527Sache *    documentation and/or other materials provided with the distribution.
166527Sache *
176527Sache * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
186527Sache * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
196527Sache * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
206527Sache * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
216527Sache * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
226527Sache * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
236527Sache * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
246527Sache * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
256527Sache * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
266527Sache * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
276527Sache * SUCH DAMAGE.
286527Sache */
296527Sache
3087243Smarkm#include <sys/cdefs.h>
3187243Smarkm__FBSDID("$FreeBSD$");
3287243Smarkm
33175038Simp#include <sys/types.h>
3418950Sache#include <ctype.h>
356527Sache#include <err.h>
36101867Sache#include <limits.h>
376527Sache#include <unistd.h>
386527Sache#include <string.h>
396527Sache#include <sysexits.h>
4087012Sache#include "common.h"
4116073Sphk#include "y.tab.h"
426527Sache
4343967Sacheint line_no = 1, save_no, fromsubs;
4487052Sacheu_char buf[BUFSIZE], *ptr;
456527SacheFILE *map_fp;
466527SacheYY_BUFFER_STATE main_buf, map_buf;
476527Sache#ifdef FLEX_DEBUG
486527SacheYYSTYPE yylval;
496527Sache#endif /* FLEX_DEBUG */
5087243Smarkmint yylex(void);
516527Sache%}
526527Sache%%
5343967Sache<INITIAL,charmap,nchar,subs,subs2>[ \t]+      ;
5443967Sache<subs2>\"               { ptr = buf; BEGIN(string); }
5543967Sache<subs>\<                { ptr = buf; fromsubs = 1; BEGIN(name); }
5643967Sache<INITIAL>\<             { ptr = buf; fromsubs = 0; BEGIN(name); }
576527Sache^#.*\n			line_no++;
586527Sache^\n			line_no++;
5918950Sache<INITIAL>\\\n           line_no++;
6043967Sache<INITIAL,nchar,subs>\\t      { yylval.ch = '\t'; return CHAR; }
6143967Sache<INITIAL,nchar,subs>\\n      { yylval.ch = '\n'; return CHAR; }
6243967Sache<INITIAL,nchar,subs>\\b      { yylval.ch = '\b'; return CHAR; }
6343967Sache<INITIAL,nchar,subs>\\f      { yylval.ch = '\f'; return CHAR; }
6443967Sache<INITIAL,nchar,subs>\\v      { yylval.ch = '\v'; return CHAR; }
6543967Sache<INITIAL,nchar,subs>\\r      { yylval.ch = '\r'; return CHAR; }
6643967Sache<INITIAL,nchar,subs>\\a      { yylval.ch = '\a'; return CHAR; }
6743967Sache<subs2>\n               {
6818950Sache	line_no++;
6918950Sache	BEGIN(INITIAL);
7018950Sache	return '\n';
7118950Sache}
7218950Sache<INITIAL,nchar>\n       {
7318950Sache	line_no++;
7418950Sache	if (map_fp != NULL) {
7518950Sache		ptr = buf;
7618950Sache		BEGIN(defn);
7718950Sache	}
7818950Sache	return '\n';
7918950Sache}
8018950Sache<INITIAL>[;,{}()]       return *yytext;
8118950Sache<INITIAL>substitute     { BEGIN(subs); return SUBSTITUTE; }
8243967Sache<subs>with              { BEGIN(subs2); return WITH; }
8318950Sache<INITIAL>order          return ORDER;
8418950Sache<INITIAL>charmap        BEGIN(charmap);
8518950Sache<INITIAL>;[ \t]*\.\.\.[ \t]*;   return RANGE;
8643967Sache<INITIAL,nchar,subs>\\[0-7]{3}       {
876527Sache	u_int v;
886527Sache
896527Sache	sscanf(&yytext[1], "%o", &v);
906527Sache	yylval.ch = (u_char)v;
916527Sache	return CHAR;
926527Sache}
93102299Sache<INITIAL,nchar,subs>\\x[0-9a-fA-F]{2}   {
946527Sache	u_int v;
956527Sache
966527Sache	sscanf(&yytext[2], "%x", &v);
976527Sache	yylval.ch = (u_char)v;
986527Sache	return CHAR;
996527Sache}
100102299Sache<INITIAL,nchar,subs>\\. { yylval.ch = yytext[1]; return CHAR; }
101102299Sache<INITIAL,nchar,subs>.   { yylval.ch = *yytext; return CHAR; }
10251890Sache<defn>^#.*\n            line_no++;
10318950Sache<defn>[ \t]+            {
10418950Sache	if (ptr == buf)
10518950Sache		errx(EX_UNAVAILABLE, "map expected near line %u of %s",
10618950Sache		     line_no, map_name);
10718950Sache	*ptr = '\0';
10818950Sache	strcpy(yylval.str, buf);
10918950Sache	BEGIN(nchar);
11018950Sache	return DEFN;
11118950Sache}
11218950Sache<name>\/\/              {
1136527Sache	if(ptr >= buf + sizeof(buf) - 1)
11443940Sache		errx(EX_UNAVAILABLE, "name buffer overflow near line %u, character '/'",
1156527Sache		     line_no);
11618950Sache	*ptr++ = '/';
11718950Sache}
11818950Sache<name>\/\>              {
11918950Sache	if(ptr >= buf + sizeof(buf) - 1)
12043940Sache		errx(EX_UNAVAILABLE, "name buffer overflow near line %u, character '>'",
12118950Sache		     line_no);
1226527Sache	*ptr++ = '>';
1236527Sache}
1246527Sache<string>\\\"		{
1256527Sache	if(ptr >= buf + sizeof(buf) - 1)
12643940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\"'",
1276527Sache		     line_no);
1286527Sache	*ptr++ = '"';
1296527Sache}
1306527Sache<name>\>		{
13118955Sache	u_int i;
13218955Sache
13318950Sache	if (ptr == buf)
13418955Sache		errx(EX_UNAVAILABLE, "non-empty name expected near line %u",
13518950Sache		     line_no);
1366527Sache	*ptr = '\0';
13787052Sache	for (i = 0; i <= UCHAR_MAX; i++) {
13818955Sache		if (strcmp(charmap_table[i], buf) == 0)
13918955Sache			goto findit;
14087052Sache	}
14118955Sache	errx(EX_UNAVAILABLE, "name <%s> not 'charmap'-defined near line %u",
14218955Sache		buf, line_no);
14387052Sache findit:
14418955Sache	yylval.ch = i;
14543967Sache	if (fromsubs)
14643967Sache		BEGIN(subs);
14743967Sache	else
14843967Sache		BEGIN(INITIAL);
14918955Sache	return CHAR;
1506527Sache}
1516527Sache<string>\"		{
1526527Sache	*ptr = '\0';
1536527Sache	strcpy(yylval.str, buf);
15443967Sache	BEGIN(subs2);
1556527Sache	return STRING;
1566527Sache}
15718950Sache<name,defn>.            {
15887243Smarkm	const char *s = (map_fp != NULL) ? map_name : "input";
15918950Sache
16018950Sache	if (!isascii(*yytext) || !isprint(*yytext))
16118950Sache		errx(EX_UNAVAILABLE, "non-ASCII or non-printable character 0x%02x not allowed in the map/name near line %u of %s",
16218950Sache		     *yytext, line_no, s);
1636527Sache	if(ptr >= buf + sizeof(buf) - 1)
16443940Sache		errx(EX_UNAVAILABLE, "map/name buffer overflow near line %u of %s, character '%c'",
16518950Sache		     line_no, s, *yytext);
1666527Sache	*ptr++ = *yytext;
1676527Sache}
16818950Sache<string>\\t             {
1696527Sache	if(ptr >= buf + sizeof(buf) - 1)
17043940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\t'",
1716527Sache		     line_no);
1726527Sache	*ptr++ = '\t';
1736527Sache}
17418950Sache<string>\\b             {
1756527Sache	if(ptr >= buf + sizeof(buf) - 1)
17643940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\b'",
1776527Sache		     line_no);
1786527Sache	*ptr++ = '\b';
1796527Sache}
18018950Sache<string>\\f             {
1816527Sache	if(ptr >= buf + sizeof(buf) - 1)
18243940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\f'",
1836527Sache		     line_no);
1846527Sache	*ptr++ = '\f';
1856527Sache}
18618950Sache<string>\\v             {
1876527Sache	if(ptr >= buf + sizeof(buf) - 1)
18843940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\v'",
1896527Sache		     line_no);
1906527Sache	*ptr++ = '\v';
1916527Sache}
19218950Sache<string>\\n             {
1936527Sache	if(ptr >= buf + sizeof(buf) - 1)
19443940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\n'",
1956527Sache		     line_no);
1966527Sache	*ptr++ = '\n';
1976527Sache}
19818950Sache<string>\\r             {
1996527Sache	if(ptr >= buf + sizeof(buf) - 1)
20043940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\r'",
2016527Sache		     line_no);
2026527Sache	*ptr++ = '\r';
2036527Sache}
20418950Sache<string>\\a             {
2056527Sache	if(ptr >= buf + sizeof(buf) - 1)
20643940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\a'",
2076527Sache		     line_no);
2086527Sache	*ptr++ = '\a';
2096527Sache}
21018950Sache<name,string,defn>\n            {
21187243Smarkm	const char *s = (map_fp != NULL) ? map_name : "input";
21218950Sache
21318950Sache	errx(EX_UNAVAILABLE, "unterminated map/name/string near line %u of %s", line_no, s);
2146527Sache}
21518950Sache<name,string,nchar><<EOF>>      {
21687243Smarkm	const char *s = (map_fp != NULL) ? map_name : "input";
21718950Sache
21818950Sache	errx(EX_UNAVAILABLE, "premature EOF in the name/string/char near line %u of %s", line_no, s);
21918950Sache}
22018950Sache<string>\\x[0-9a-f]{2}          {
2216527Sache	u_int v;
2226527Sache
2236527Sache	sscanf(&yytext[2], "%x", &v);
2246527Sache	*ptr++ = (u_char)v;
2256527Sache}
22618950Sache<string>\\[0-7]{3}              {
2276527Sache	u_int v;
2286527Sache
2296527Sache	sscanf(&yytext[1], "%o", &v);
2306527Sache	*ptr++ = (u_char)v;
2316527Sache}
23218950Sache<string>\\.             {
23318950Sache	if(ptr >= buf + sizeof(buf) - 1)
23443940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '%c'",
23518950Sache		     line_no, yytext[1]);
23618950Sache	*ptr++ = yytext[1];
23718950Sache}
23818950Sache<string>.               {
23918950Sache	if(ptr >= buf + sizeof(buf) - 1)
24043940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '%c'",
24118950Sache		     line_no, *yytext);
24218950Sache	*ptr++ = *yytext;
24318950Sache}
2446527Sache<charmap>[^ \t\n]+	{
24518950Sache	strcat(map_name, "/");
24618950Sache	strcat(map_name, yytext);
24718950Sache	if((map_fp = fopen(map_name, "r")) == NULL)
24818950Sache		err(EX_UNAVAILABLE, "can't open 'charmap' file %s",
24918950Sache		    map_name);
25018950Sache	save_no = line_no;
25118950Sache	line_no = 1;
2526527Sache	map_buf = yy_new_buffer(map_fp, YY_BUF_SIZE);
2536527Sache	main_buf = YY_CURRENT_BUFFER;
2546527Sache	yy_switch_to_buffer(map_buf);
25518950Sache	ptr = buf;
25618950Sache	BEGIN(defn);
2576527Sache}
25818950Sache<charmap>\n             {
25918950Sache	errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u",
2606527Sache	     line_no);
2616527Sache}
26218950Sache<charmap><<EOF>>        {
26318950Sache	errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u",
26418950Sache	     line_no);
26518950Sache}
26618950Sache<INITIAL,defn><<EOF>>                 {
26718950Sache	if(map_fp != NULL) {
26818950Sache		if (ptr != buf)
26918950Sache			errx(EX_UNAVAILABLE, "premature EOF in the map near line %u of %s", line_no, map_name);
2706527Sache		yy_switch_to_buffer(main_buf);
2716527Sache		yy_delete_buffer(map_buf);
2726527Sache		fclose(map_fp);
27318950Sache		map_fp = NULL;
27418950Sache		line_no = save_no;
27518950Sache		BEGIN(INITIAL);
27618950Sache	} else
2776527Sache		yyterminate();
2786527Sache}
2796527Sache%%
2806527Sache#ifdef FLEX_DEBUG
2816527Sachemain()
2826527Sache{
2836527Sache	while(yylex())
2846527Sache		;
2856527Sache	return 0;
2866527Sache}
2876527Sache#endif /* FLEX_DEBUG */
288