scan.l revision 101867
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: head/usr.bin/colldef/scan.l 101867 2002-08-14 11:59:57Z ache $");
3287243Smarkm
3318950Sache#include <ctype.h>
346527Sache#include <err.h>
35101867Sache#include <limits.h>
366527Sache#include <unistd.h>
376527Sache#include <string.h>
386527Sache#include <sysexits.h>
3987012Sache#include "common.h"
4016073Sphk#include "y.tab.h"
416527Sache
4243967Sacheint line_no = 1, save_no, fromsubs;
4387052Sacheu_char buf[BUFSIZE], *ptr;
446527SacheFILE *map_fp;
456527SacheYY_BUFFER_STATE main_buf, map_buf;
466527Sache#ifdef FLEX_DEBUG
476527SacheYYSTYPE yylval;
486527Sache#endif /* FLEX_DEBUG */
4987243Smarkmint yylex(void);
506527Sache%}
516527Sache%%
5243967Sache<INITIAL,charmap,nchar,subs,subs2>[ \t]+      ;
5343967Sache<subs2>\"               { ptr = buf; BEGIN(string); }
5443967Sache<subs>\<                { ptr = buf; fromsubs = 1; BEGIN(name); }
5543967Sache<INITIAL>\<             { ptr = buf; fromsubs = 0; BEGIN(name); }
566527Sache^#.*\n			line_no++;
576527Sache^\n			line_no++;
5818950Sache<INITIAL>\\\n           line_no++;
5943967Sache<INITIAL,nchar,subs>\\t      { yylval.ch = '\t'; return CHAR; }
6043967Sache<INITIAL,nchar,subs>\\n      { yylval.ch = '\n'; return CHAR; }
6143967Sache<INITIAL,nchar,subs>\\b      { yylval.ch = '\b'; return CHAR; }
6243967Sache<INITIAL,nchar,subs>\\f      { yylval.ch = '\f'; return CHAR; }
6343967Sache<INITIAL,nchar,subs>\\v      { yylval.ch = '\v'; return CHAR; }
6443967Sache<INITIAL,nchar,subs>\\r      { yylval.ch = '\r'; return CHAR; }
6543967Sache<INITIAL,nchar,subs>\\a      { yylval.ch = '\a'; return CHAR; }
6643967Sache<INITIAL,nchar,subs>\\.      { yylval.ch = yytext[1]; 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}
9343967Sache<INITIAL,nchar,subs>\\x[0-9a-z]{2}   {
946527Sache	u_int v;
956527Sache
966527Sache	sscanf(&yytext[2], "%x", &v);
976527Sache	yylval.ch = (u_char)v;
986527Sache	return CHAR;
996527Sache}
10018950Sache<INITIAL>[^;,{}() \t\n"<]+      {
1016527Sache	if(yyleng == 1) {
1026527Sache		yylval.ch = *yytext;
1036527Sache		return CHAR;
1046527Sache	}
10587052Sache	if(yyleng > BUFSIZE - 1)
10643940Sache		errx(EX_UNAVAILABLE, "chain buffer overflow near line %u",
1076527Sache		     line_no);
1086527Sache	strcpy(yylval.str, yytext);
1096527Sache	return CHAIN;
1106527Sache}
11143967Sache<nchar,subs>.                {
11218950Sache	yylval.ch = *yytext;
11318950Sache	return CHAR;
11418950Sache}
11551890Sache<defn>^#.*\n            line_no++;
11618950Sache<defn>[ \t]+            {
11718950Sache	if (ptr == buf)
11818950Sache		errx(EX_UNAVAILABLE, "map expected near line %u of %s",
11918950Sache		     line_no, map_name);
12018950Sache	*ptr = '\0';
12118950Sache	strcpy(yylval.str, buf);
12218950Sache	BEGIN(nchar);
12318950Sache	return DEFN;
12418950Sache}
12518950Sache<name>\/\/              {
1266527Sache	if(ptr >= buf + sizeof(buf) - 1)
12743940Sache		errx(EX_UNAVAILABLE, "name buffer overflow near line %u, character '/'",
1286527Sache		     line_no);
12918950Sache	*ptr++ = '/';
13018950Sache}
13118950Sache<name>\/\>              {
13218950Sache	if(ptr >= buf + sizeof(buf) - 1)
13343940Sache		errx(EX_UNAVAILABLE, "name buffer overflow near line %u, character '>'",
13418950Sache		     line_no);
1356527Sache	*ptr++ = '>';
1366527Sache}
1376527Sache<string>\\\"		{
1386527Sache	if(ptr >= buf + sizeof(buf) - 1)
13943940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\"'",
1406527Sache		     line_no);
1416527Sache	*ptr++ = '"';
1426527Sache}
1436527Sache<name>\>		{
14418955Sache	u_int i;
14518955Sache
14618950Sache	if (ptr == buf)
14718955Sache		errx(EX_UNAVAILABLE, "non-empty name expected near line %u",
14818950Sache		     line_no);
1496527Sache	*ptr = '\0';
15087052Sache	for (i = 0; i <= UCHAR_MAX; i++) {
15118955Sache		if (strcmp(charmap_table[i], buf) == 0)
15218955Sache			goto findit;
15387052Sache	}
15418955Sache	errx(EX_UNAVAILABLE, "name <%s> not 'charmap'-defined near line %u",
15518955Sache		buf, line_no);
15687052Sache findit:
15718955Sache	yylval.ch = i;
15843967Sache	if (fromsubs)
15943967Sache		BEGIN(subs);
16043967Sache	else
16143967Sache		BEGIN(INITIAL);
16218955Sache	return CHAR;
1636527Sache}
1646527Sache<string>\"		{
1656527Sache	*ptr = '\0';
1666527Sache	strcpy(yylval.str, buf);
16743967Sache	BEGIN(subs2);
1686527Sache	return STRING;
1696527Sache}
17018950Sache<name,defn>.            {
17187243Smarkm	const char *s = (map_fp != NULL) ? map_name : "input";
17218950Sache
17318950Sache	if (!isascii(*yytext) || !isprint(*yytext))
17418950Sache		errx(EX_UNAVAILABLE, "non-ASCII or non-printable character 0x%02x not allowed in the map/name near line %u of %s",
17518950Sache		     *yytext, line_no, s);
1766527Sache	if(ptr >= buf + sizeof(buf) - 1)
17743940Sache		errx(EX_UNAVAILABLE, "map/name buffer overflow near line %u of %s, character '%c'",
17818950Sache		     line_no, s, *yytext);
1796527Sache	*ptr++ = *yytext;
1806527Sache}
18118950Sache<string>\\t             {
1826527Sache	if(ptr >= buf + sizeof(buf) - 1)
18343940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\t'",
1846527Sache		     line_no);
1856527Sache	*ptr++ = '\t';
1866527Sache}
18718950Sache<string>\\b             {
1886527Sache	if(ptr >= buf + sizeof(buf) - 1)
18943940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\b'",
1906527Sache		     line_no);
1916527Sache	*ptr++ = '\b';
1926527Sache}
19318950Sache<string>\\f             {
1946527Sache	if(ptr >= buf + sizeof(buf) - 1)
19543940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\f'",
1966527Sache		     line_no);
1976527Sache	*ptr++ = '\f';
1986527Sache}
19918950Sache<string>\\v             {
2006527Sache	if(ptr >= buf + sizeof(buf) - 1)
20143940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\v'",
2026527Sache		     line_no);
2036527Sache	*ptr++ = '\v';
2046527Sache}
20518950Sache<string>\\n             {
2066527Sache	if(ptr >= buf + sizeof(buf) - 1)
20743940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\n'",
2086527Sache		     line_no);
2096527Sache	*ptr++ = '\n';
2106527Sache}
21118950Sache<string>\\r             {
2126527Sache	if(ptr >= buf + sizeof(buf) - 1)
21343940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\r'",
2146527Sache		     line_no);
2156527Sache	*ptr++ = '\r';
2166527Sache}
21718950Sache<string>\\a             {
2186527Sache	if(ptr >= buf + sizeof(buf) - 1)
21943940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\a'",
2206527Sache		     line_no);
2216527Sache	*ptr++ = '\a';
2226527Sache}
22318950Sache<name,string,defn>\n            {
22487243Smarkm	const char *s = (map_fp != NULL) ? map_name : "input";
22518950Sache
22618950Sache	errx(EX_UNAVAILABLE, "unterminated map/name/string near line %u of %s", line_no, s);
2276527Sache}
22818950Sache<name,string,nchar><<EOF>>      {
22987243Smarkm	const char *s = (map_fp != NULL) ? map_name : "input";
23018950Sache
23118950Sache	errx(EX_UNAVAILABLE, "premature EOF in the name/string/char near line %u of %s", line_no, s);
23218950Sache}
23318950Sache<string>\\x[0-9a-f]{2}          {
2346527Sache	u_int v;
2356527Sache
2366527Sache	sscanf(&yytext[2], "%x", &v);
2376527Sache	*ptr++ = (u_char)v;
2386527Sache}
23918950Sache<string>\\[0-7]{3}              {
2406527Sache	u_int v;
2416527Sache
2426527Sache	sscanf(&yytext[1], "%o", &v);
2436527Sache	*ptr++ = (u_char)v;
2446527Sache}
24518950Sache<string>\\.             {
24618950Sache	if(ptr >= buf + sizeof(buf) - 1)
24743940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '%c'",
24818950Sache		     line_no, yytext[1]);
24918950Sache	*ptr++ = yytext[1];
25018950Sache}
25118950Sache<string>.               {
25218950Sache	if(ptr >= buf + sizeof(buf) - 1)
25343940Sache		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '%c'",
25418950Sache		     line_no, *yytext);
25518950Sache	*ptr++ = *yytext;
25618950Sache}
2576527Sache<charmap>[^ \t\n]+	{
25818950Sache	strcat(map_name, "/");
25918950Sache	strcat(map_name, yytext);
26018950Sache	if((map_fp = fopen(map_name, "r")) == NULL)
26118950Sache		err(EX_UNAVAILABLE, "can't open 'charmap' file %s",
26218950Sache		    map_name);
26318950Sache	save_no = line_no;
26418950Sache	line_no = 1;
2656527Sache	map_buf = yy_new_buffer(map_fp, YY_BUF_SIZE);
2666527Sache	main_buf = YY_CURRENT_BUFFER;
2676527Sache	yy_switch_to_buffer(map_buf);
26818950Sache	ptr = buf;
26918950Sache	BEGIN(defn);
2706527Sache}
27118950Sache<charmap>\n             {
27218950Sache	errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u",
2736527Sache	     line_no);
2746527Sache}
27518950Sache<charmap><<EOF>>        {
27618950Sache	errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u",
27718950Sache	     line_no);
27818950Sache}
27918950Sache<INITIAL,defn><<EOF>>                 {
28018950Sache	if(map_fp != NULL) {
28118950Sache		if (ptr != buf)
28218950Sache			errx(EX_UNAVAILABLE, "premature EOF in the map near line %u of %s", line_no, map_name);
2836527Sache		yy_switch_to_buffer(main_buf);
2846527Sache		yy_delete_buffer(map_buf);
2856527Sache		fclose(map_fp);
28618950Sache		map_fp = NULL;
28718950Sache		line_no = save_no;
28818950Sache		BEGIN(INITIAL);
28918950Sache	} else
2906527Sache		yyterminate();
2916527Sache}
2926527Sache%%
2936527Sache#ifdef FLEX_DEBUG
2946527Sachemain()
2956527Sache{
2966527Sache	while(yylex())
2976527Sache		;
2986527Sache	return 0;
2996527Sache}
3006527Sache#endif /* FLEX_DEBUG */
301