scan.l revision 18950
118950Sache%x string name charmap defn nchar subs
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 *
2918950Sache * $Id: scan.l,v 1.3 1996/06/02 17:18:18 phk Exp $
306527Sache */
316527Sache
3218950Sache#include <ctype.h>
336527Sache#include <err.h>
346527Sache#include <unistd.h>
356527Sache#include <string.h>
366527Sache#include <sysexits.h>
376527Sache#include "collate.h"
3816073Sphk#include "y.tab.h"
396527Sache
4018950Sacheint line_no = 1, save_no;
416527Sacheu_char buf[STR_LEN], *ptr;
426527SacheFILE *map_fp;
4318950Sacheextern char map_name[];
446527SacheYY_BUFFER_STATE main_buf, map_buf;
456527Sache#ifdef FLEX_DEBUG
466527SacheYYSTYPE yylval;
476527Sache#endif /* FLEX_DEBUG */
486527Sache%}
496527Sache%%
5018950Sache<INITIAL,charmap,nchar,subs>[ \t]+      ;
5118950Sache<subs>\"                { ptr = buf; BEGIN(string); }
5218950Sache<INITIAL>\<             { ptr = buf; BEGIN(name); }
536527Sache^#.*\n			line_no++;
546527Sache^\n			line_no++;
5518950Sache<INITIAL>\\\n           line_no++;
5618950Sache<INITIAL,nchar>\\t      { yylval.ch = '\t'; return CHAR; }
5718950Sache<INITIAL,nchar>\\n      { yylval.ch = '\n'; return CHAR; }
5818950Sache<INITIAL,nchar>\\b      { yylval.ch = '\b'; return CHAR; }
5918950Sache<INITIAL,nchar>\\f      { yylval.ch = '\f'; return CHAR; }
6018950Sache<INITIAL,nchar>\\v      { yylval.ch = '\v'; return CHAR; }
6118950Sache<INITIAL,nchar>\\r      { yylval.ch = '\r'; return CHAR; }
6218950Sache<INITIAL,nchar>\\a      { yylval.ch = '\a'; return CHAR; }
6318950Sache<INITIAL,nchar>\\.      { yylval.ch = yytext[1]; return CHAR; }
6418950Sache<subs>\n                {
6518950Sache	line_no++;
6618950Sache	BEGIN(INITIAL);
6718950Sache	return '\n';
6818950Sache}
6918950Sache<INITIAL,nchar>\n       {
7018950Sache	line_no++;
7118950Sache	if (map_fp != NULL) {
7218950Sache		ptr = buf;
7318950Sache		BEGIN(defn);
7418950Sache	}
7518950Sache	return '\n';
7618950Sache}
7718950Sache<INITIAL>[;,{}()]       return *yytext;
7818950Sache<INITIAL>substitute     { BEGIN(subs); return SUBSTITUTE; }
7918950Sache<subs>with              return WITH;
8018950Sache<INITIAL>order          return ORDER;
8118950Sache<INITIAL>charmap        BEGIN(charmap);
8218950Sache<INITIAL>;[ \t]*\.\.\.[ \t]*;   return RANGE;
8318950Sache<INITIAL,nchar>\\[0-7]{3}       {
846527Sache	u_int v;
856527Sache
866527Sache	sscanf(&yytext[1], "%o", &v);
876527Sache	yylval.ch = (u_char)v;
886527Sache	return CHAR;
896527Sache}
9018950Sache<INITIAL,nchar>\\x[0-9a-z]{2}   {
916527Sache	u_int v;
926527Sache
936527Sache	sscanf(&yytext[2], "%x", &v);
946527Sache	yylval.ch = (u_char)v;
956527Sache	return CHAR;
966527Sache}
9718950Sache<INITIAL>[^;,{}() \t\n"<]+      {
986527Sache	if(yyleng == 1) {
996527Sache		yylval.ch = *yytext;
1006527Sache		return CHAR;
1016527Sache	}
1026527Sache	if(yyleng > STR_LEN - 1)
1036527Sache		errx(EX_UNAVAILABLE, "chain buffer overflaw near line %u",
1046527Sache		     line_no);
1056527Sache	strcpy(yylval.str, yytext);
1066527Sache	return CHAIN;
1076527Sache}
10818950Sache<nchar>.                {
10918950Sache	yylval.ch = *yytext;
11018950Sache	return CHAR;
11118950Sache}
11218950Sache<defn>[ \t]+            {
11318950Sache	if (ptr == buf)
11418950Sache		errx(EX_UNAVAILABLE, "map expected near line %u of %s",
11518950Sache		     line_no, map_name);
11618950Sache	*ptr = '\0';
11718950Sache	strcpy(yylval.str, buf);
11818950Sache	BEGIN(nchar);
11918950Sache	return DEFN;
12018950Sache}
12118950Sache<name>\/\/              {
1226527Sache	if(ptr >= buf + sizeof(buf) - 1)
12318950Sache		errx(EX_UNAVAILABLE, "name buffer overflaw near line %u, character '/'",
1246527Sache		     line_no);
12518950Sache	*ptr++ = '/';
12618950Sache}
12718950Sache<name>\/\>              {
12818950Sache	if(ptr >= buf + sizeof(buf) - 1)
12918950Sache		errx(EX_UNAVAILABLE, "name buffer overflaw near line %u, character '>'",
13018950Sache		     line_no);
1316527Sache	*ptr++ = '>';
1326527Sache}
1336527Sache<string>\\\"		{
1346527Sache	if(ptr >= buf + sizeof(buf) - 1)
13518950Sache		errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\"'",
1366527Sache		     line_no);
1376527Sache	*ptr++ = '"';
1386527Sache}
1396527Sache<name>\>		{
14018950Sache	if (ptr == buf)
14118950Sache		errx(EX_UNAVAILABLE, "name expected near line %u",
14218950Sache		     line_no);
1436527Sache	*ptr = '\0';
1446527Sache	strcpy(yylval.str, buf);
1456527Sache	BEGIN(INITIAL);
1466527Sache	return NAME;
1476527Sache}
1486527Sache<string>\"		{
1496527Sache	*ptr = '\0';
1506527Sache	strcpy(yylval.str, buf);
15118950Sache	BEGIN(subs);
1526527Sache	return STRING;
1536527Sache}
15418950Sache<name,defn>.            {
15518950Sache	char *s = (map_fp != NULL) ? map_name : "input";
15618950Sache
15718950Sache	if (!isascii(*yytext) || !isprint(*yytext))
15818950Sache		errx(EX_UNAVAILABLE, "non-ASCII or non-printable character 0x%02x not allowed in the map/name near line %u of %s",
15918950Sache		     *yytext, line_no, s);
1606527Sache	if(ptr >= buf + sizeof(buf) - 1)
16118950Sache		errx(EX_UNAVAILABLE, "map/name buffer overflaw near line %u of %s, character '%c'",
16218950Sache		     line_no, s, *yytext);
1636527Sache	*ptr++ = *yytext;
1646527Sache}
16518950Sache<string>\\t             {
1666527Sache	if(ptr >= buf + sizeof(buf) - 1)
16718950Sache		errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\t'",
1686527Sache		     line_no);
1696527Sache	*ptr++ = '\t';
1706527Sache}
17118950Sache<string>\\b             {
1726527Sache	if(ptr >= buf + sizeof(buf) - 1)
17318950Sache		errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\b'",
1746527Sache		     line_no);
1756527Sache	*ptr++ = '\b';
1766527Sache}
17718950Sache<string>\\f             {
1786527Sache	if(ptr >= buf + sizeof(buf) - 1)
17918950Sache		errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\f'",
1806527Sache		     line_no);
1816527Sache	*ptr++ = '\f';
1826527Sache}
18318950Sache<string>\\v             {
1846527Sache	if(ptr >= buf + sizeof(buf) - 1)
18518950Sache		errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\v'",
1866527Sache		     line_no);
1876527Sache	*ptr++ = '\v';
1886527Sache}
18918950Sache<string>\\n             {
1906527Sache	if(ptr >= buf + sizeof(buf) - 1)
19118950Sache		errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\n'",
1926527Sache		     line_no);
1936527Sache	*ptr++ = '\n';
1946527Sache}
19518950Sache<string>\\r             {
1966527Sache	if(ptr >= buf + sizeof(buf) - 1)
19718950Sache		errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\r'",
1986527Sache		     line_no);
1996527Sache	*ptr++ = '\r';
2006527Sache}
20118950Sache<string>\\a             {
2026527Sache	if(ptr >= buf + sizeof(buf) - 1)
20318950Sache		errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\a'",
2046527Sache		     line_no);
2056527Sache	*ptr++ = '\a';
2066527Sache}
20718950Sache<name,string,defn>\n            {
20818950Sache	char *s = (map_fp != NULL) ? map_name : "input";
20918950Sache
21018950Sache	errx(EX_UNAVAILABLE, "unterminated map/name/string near line %u of %s", line_no, s);
2116527Sache}
21218950Sache<name,string,nchar><<EOF>>      {
21318950Sache	char *s = (map_fp != NULL) ? map_name : "input";
21418950Sache
21518950Sache	errx(EX_UNAVAILABLE, "premature EOF in the name/string/char near line %u of %s", line_no, s);
21618950Sache}
21718950Sache<string>\\x[0-9a-f]{2}          {
2186527Sache	u_int v;
2196527Sache
2206527Sache	sscanf(&yytext[2], "%x", &v);
2216527Sache	*ptr++ = (u_char)v;
2226527Sache}
22318950Sache<string>\\[0-7]{3}              {
2246527Sache	u_int v;
2256527Sache
2266527Sache	sscanf(&yytext[1], "%o", &v);
2276527Sache	*ptr++ = (u_char)v;
2286527Sache}
22918950Sache<string>\\.             {
23018950Sache	if(ptr >= buf + sizeof(buf) - 1)
23118950Sache		errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '%c'",
23218950Sache		     line_no, yytext[1]);
23318950Sache	*ptr++ = yytext[1];
23418950Sache}
23518950Sache<string>.               {
23618950Sache	if(ptr >= buf + sizeof(buf) - 1)
23718950Sache		errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '%c'",
23818950Sache		     line_no, *yytext);
23918950Sache	*ptr++ = *yytext;
24018950Sache}
2416527Sache<charmap>[^ \t\n]+	{
24218950Sache	strcat(map_name, "/");
24318950Sache	strcat(map_name, yytext);
24418950Sache	if((map_fp = fopen(map_name, "r")) == NULL)
24518950Sache		err(EX_UNAVAILABLE, "can't open 'charmap' file %s",
24618950Sache		    map_name);
24718950Sache	save_no = line_no;
24818950Sache	line_no = 1;
2496527Sache	map_buf = yy_new_buffer(map_fp, YY_BUF_SIZE);
2506527Sache	main_buf = YY_CURRENT_BUFFER;
2516527Sache	yy_switch_to_buffer(map_buf);
25218950Sache	ptr = buf;
25318950Sache	BEGIN(defn);
2546527Sache}
25518950Sache<charmap>\n             {
25618950Sache	errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u",
2576527Sache	     line_no);
2586527Sache}
25918950Sache<charmap><<EOF>>        {
26018950Sache	errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u",
26118950Sache	     line_no);
26218950Sache}
26318950Sache<INITIAL,defn><<EOF>>                 {
26418950Sache	if(map_fp != NULL) {
26518950Sache		if (ptr != buf)
26618950Sache			errx(EX_UNAVAILABLE, "premature EOF in the map near line %u of %s", line_no, map_name);
2676527Sache		yy_switch_to_buffer(main_buf);
2686527Sache		yy_delete_buffer(map_buf);
2696527Sache		fclose(map_fp);
27018950Sache		map_fp = NULL;
27118950Sache		line_no = save_no;
27218950Sache		BEGIN(INITIAL);
27318950Sache	} else
2746527Sache		yyterminate();
2756527Sache}
2766527Sache%%
2776527Sache#ifdef FLEX_DEBUG
2786527Sachemain()
2796527Sache{
2806527Sache	while(yylex())
2816527Sache		;
2826527Sache	return 0;
2836527Sache}
2846527Sache#endif /* FLEX_DEBUG */
285