scan.l revision 87050
1239310Sdim%x string name charmap defn nchar subs subs2
2239310Sdim%{
3353358Sdim/*-
4353358Sdim * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
5353358Sdim *		at Electronni Visti IA, Kiev, Ukraine.
6239310Sdim *			All rights reserved.
7239310Sdim *
8239310Sdim * Redistribution and use in source and binary forms, with or without
9239310Sdim * modification, are permitted provided that the following conditions
10239310Sdim * are met:
11239310Sdim * 1. Redistributions of source code must retain the above copyright
12239310Sdim *    notice, this list of conditions and the following disclaimer.
13321369Sdim * 2. Redistributions in binary form must reproduce the above copyright
14239310Sdim *    notice, this list of conditions and the following disclaimer in the
15249423Sdim *    documentation and/or other materials provided with the distribution.
16249423Sdim *
17280031Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
18288943Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19353358Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20314564Sdim * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
21314564Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22314564Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23239310Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24309124Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25288943Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26314564Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27249423Sdim * SUCH DAMAGE.
28239310Sdim *
29239310Sdim * $FreeBSD: head/usr.bin/colldef/scan.l 87050 2001-11-28 09:26:57Z ache $
30239310Sdim */
31321369Sdim
32239310Sdim#include <ctype.h>
33309124Sdim#include <err.h>
34314564Sdim#include <unistd.h>
35314564Sdim#include <string.h>
36314564Sdim#include <sysexits.h>
37239310Sdim#include "collate.h"
38239310Sdim#include "common.h"
39239310Sdim#include "y.tab.h"
40314564Sdim
41314564Sdimint line_no = 1, save_no, fromsubs;
42314564Sdimu_char buf[80], *ptr;
43314564SdimFILE *map_fp;
44314564SdimYY_BUFFER_STATE main_buf, map_buf;
45314564Sdim#ifdef FLEX_DEBUG
46309124SdimYYSTYPE yylval;
47335799Sdim#endif /* FLEX_DEBUG */
48335799Sdim%}
49335799Sdim%%
50335799Sdim<INITIAL,charmap,nchar,subs,subs2>[ \t]+      ;
51335799Sdim<subs2>\"               { ptr = buf; BEGIN(string); }
52335799Sdim<subs>\<                { ptr = buf; fromsubs = 1; BEGIN(name); }
53335799Sdim<INITIAL>\<             { ptr = buf; fromsubs = 0; BEGIN(name); }
54335799Sdim^#.*\n			line_no++;
55341825Sdim^\n			line_no++;
56341825Sdim<INITIAL>\\\n           line_no++;
57341825Sdim<INITIAL,nchar,subs>\\t      { yylval.ch = '\t'; return CHAR; }
58341825Sdim<INITIAL,nchar,subs>\\n      { yylval.ch = '\n'; return CHAR; }
59341825Sdim<INITIAL,nchar,subs>\\b      { yylval.ch = '\b'; return CHAR; }
60341825Sdim<INITIAL,nchar,subs>\\f      { yylval.ch = '\f'; return CHAR; }
61249423Sdim<INITIAL,nchar,subs>\\v      { yylval.ch = '\v'; return CHAR; }
62314564Sdim<INITIAL,nchar,subs>\\r      { yylval.ch = '\r'; return CHAR; }
63309124Sdim<INITIAL,nchar,subs>\\a      { yylval.ch = '\a'; return CHAR; }
64249423Sdim<INITIAL,nchar,subs>\\.      { yylval.ch = yytext[1]; return CHAR; }
65251662Sdim<subs2>\n               {
66288943Sdim	line_no++;
67276479Sdim	BEGIN(INITIAL);
68296417Sdim	return '\n';
69314564Sdim}
70288943Sdim<INITIAL,nchar>\n       {
71344779Sdim	line_no++;
72239310Sdim	if (map_fp != NULL) {
73314564Sdim		ptr = buf;
74314564Sdim		BEGIN(defn);
75360784Sdim	}
76239310Sdim	return '\n';
77314564Sdim}
78314564Sdim<INITIAL>[;,{}()]       return *yytext;
79239310Sdim<INITIAL>substitute     { BEGIN(subs); return SUBSTITUTE; }
80249423Sdim<subs>with              { BEGIN(subs2); return WITH; }
81249423Sdim<INITIAL>order          return ORDER;
82296417Sdim<INITIAL>charmap        BEGIN(charmap);
83296417Sdim<INITIAL>;[ \t]*\.\.\.[ \t]*;   return RANGE;
84309124Sdim<INITIAL,nchar,subs>\\[0-7]{3}       {
85296417Sdim	u_int v;
86296417Sdim
87296417Sdim	sscanf(&yytext[1], "%o", &v);
88314564Sdim	yylval.ch = (u_char)v;
89296417Sdim	return CHAR;
90296417Sdim}
91344779Sdim<INITIAL,nchar,subs>\\x[0-9a-z]{2}   {
92239310Sdim	u_int v;
93239310Sdim
94341825Sdim	sscanf(&yytext[2], "%x", &v);
95288943Sdim	yylval.ch = (u_char)v;
96288943Sdim	return CHAR;
97288943Sdim}
98288943Sdim<INITIAL>[^;,{}() \t\n"<]+      {
99341825Sdim	if(yyleng == 1) {
100341825Sdim		yylval.ch = *yytext;
101288943Sdim		return CHAR;
102327952Sdim	}
103288943Sdim	if(yyleng > STR_LEN - 1)
104288943Sdim		errx(EX_UNAVAILABLE, "chain buffer overflow near line %u",
105288943Sdim		     line_no);
106288943Sdim	strcpy(yylval.str, yytext);
107288943Sdim	return CHAIN;
108276479Sdim}
109276479Sdim<nchar,subs>.                {
110309124Sdim	yylval.ch = *yytext;
111327952Sdim	return CHAR;
112276479Sdim}
113309124Sdim<defn>^#.*\n            line_no++;
114309124Sdim<defn>[ \t]+            {
115341825Sdim	if (ptr == buf)
116341825Sdim		errx(EX_UNAVAILABLE, "map expected near line %u of %s",
117344779Sdim		     line_no, map_name);
118341825Sdim	*ptr = '\0';
119360784Sdim	strcpy(yylval.str, buf);
120288943Sdim	BEGIN(nchar);
121288943Sdim	return DEFN;
122288943Sdim}
123288943Sdim<name>\/\/              {
124288943Sdim	if(ptr >= buf + sizeof(buf) - 1)
125335799Sdim		errx(EX_UNAVAILABLE, "name buffer overflow near line %u, character '/'",
126335799Sdim		     line_no);
127261991Sdim	*ptr++ = '/';
128261991Sdim}
129239310Sdim<name>\/\>              {
130314564Sdim	if(ptr >= buf + sizeof(buf) - 1)
131280031Sdim		errx(EX_UNAVAILABLE, "name buffer overflow near line %u, character '>'",
132239310Sdim		     line_no);
133239310Sdim	*ptr++ = '>';
134288943Sdim}
135288943Sdim<string>\\\"		{
136288943Sdim	if(ptr >= buf + sizeof(buf) - 1)
137309124Sdim		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\"'",
138327952Sdim		     line_no);
139327952Sdim	*ptr++ = '"';
140249423Sdim}
141239310Sdim<name>\>		{
142239310Sdim	u_int i;
143239310Sdim
144288943Sdim	if (ptr == buf)
145288943Sdim		errx(EX_UNAVAILABLE, "non-empty name expected near line %u",
146288943Sdim		     line_no);
147309124Sdim	*ptr = '\0';
148327952Sdim	for (i = 0; i <= UCHAR_MAX; i++)
149327952Sdim		if (strcmp(charmap_table[i], buf) == 0)
150249423Sdim			goto findit;
151239310Sdim	errx(EX_UNAVAILABLE, "name <%s> not 'charmap'-defined near line %u",
152261991Sdim		buf, line_no);
153314564Sdim	findit:
154239310Sdim	yylval.ch = i;
155239310Sdim	if (fromsubs)
156321369Sdim		BEGIN(subs);
157249423Sdim	else
158239310Sdim		BEGIN(INITIAL);
159239310Sdim	return CHAR;
160239310Sdim}
161239310Sdim<string>\"		{
162239310Sdim	*ptr = '\0';
163276479Sdim	strcpy(yylval.str, buf);
164276479Sdim	BEGIN(subs2);
165344779Sdim	return STRING;
166280031Sdim}
167276479Sdim<name,defn>.            {
168261991Sdim	char *s = (map_fp != NULL) ? map_name : "input";
169276479Sdim
170353358Sdim	if (!isascii(*yytext) || !isprint(*yytext))
171353358Sdim		errx(EX_UNAVAILABLE, "non-ASCII or non-printable character 0x%02x not allowed in the map/name near line %u of %s",
172296417Sdim		     *yytext, line_no, s);
173353358Sdim	if(ptr >= buf + sizeof(buf) - 1)
174353358Sdim		errx(EX_UNAVAILABLE, "map/name buffer overflow near line %u of %s, character '%c'",
175353358Sdim		     line_no, s, *yytext);
176353358Sdim	*ptr++ = *yytext;
177353358Sdim}
178353358Sdim<string>\\t             {
179353358Sdim	if(ptr >= buf + sizeof(buf) - 1)
180353358Sdim		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\t'",
181296417Sdim		     line_no);
182309124Sdim	*ptr++ = '\t';
183309124Sdim}
184296417Sdim<string>\\b             {
185309124Sdim	if(ptr >= buf + sizeof(buf) - 1)
186309124Sdim		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\b'",
187309124Sdim		     line_no);
188309124Sdim	*ptr++ = '\b';
189309124Sdim}
190309124Sdim<string>\\f             {
191239310Sdim	if(ptr >= buf + sizeof(buf) - 1)
192314564Sdim		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\f'",
193261991Sdim		     line_no);
194239310Sdim	*ptr++ = '\f';
195239310Sdim}
196321369Sdim<string>\\v             {
197239310Sdim	if(ptr >= buf + sizeof(buf) - 1)
198239310Sdim		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\v'",
199321369Sdim		     line_no);
200321369Sdim	*ptr++ = '\v';
201321369Sdim}
202321369Sdim<string>\\n             {
203344779Sdim	if(ptr >= buf + sizeof(buf) - 1)
204321369Sdim		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\n'",
205321369Sdim		     line_no);
206309124Sdim	*ptr++ = '\n';
207309124Sdim}
208327952Sdim<string>\\r             {
209327952Sdim	if(ptr >= buf + sizeof(buf) - 1)
210327952Sdim		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\r'",
211280031Sdim		     line_no);
212280031Sdim	*ptr++ = '\r';
213296417Sdim}
214296417Sdim<string>\\a             {
215296417Sdim	if(ptr >= buf + sizeof(buf) - 1)
216296417Sdim		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\a'",
217296417Sdim		     line_no);
218296417Sdim	*ptr++ = '\a';
219296417Sdim}
220309124Sdim<name,string,defn>\n            {
221314564Sdim	char *s = (map_fp != NULL) ? map_name : "input";
222288943Sdim
223288943Sdim	errx(EX_UNAVAILABLE, "unterminated map/name/string near line %u of %s", line_no, s);
224288943Sdim}
225321369Sdim<name,string,nchar><<EOF>>      {
226309124Sdim	char *s = (map_fp != NULL) ? map_name : "input";
227296417Sdim
228309124Sdim	errx(EX_UNAVAILABLE, "premature EOF in the name/string/char near line %u of %s", line_no, s);
229276479Sdim}
230296417Sdim<string>\\x[0-9a-f]{2}          {
231288943Sdim	u_int v;
232288943Sdim
233288943Sdim	sscanf(&yytext[2], "%x", &v);
234288943Sdim	*ptr++ = (u_char)v;
235288943Sdim}
236288943Sdim<string>\\[0-7]{3}              {
237296417Sdim	u_int v;
238288943Sdim
239288943Sdim	sscanf(&yytext[1], "%o", &v);
240288943Sdim	*ptr++ = (u_char)v;
241288943Sdim}
242288943Sdim<string>\\.             {
243309124Sdim	if(ptr >= buf + sizeof(buf) - 1)
244296417Sdim		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '%c'",
245309124Sdim		     line_no, yytext[1]);
246309124Sdim	*ptr++ = yytext[1];
247309124Sdim}
248309124Sdim<string>.               {
249309124Sdim	if(ptr >= buf + sizeof(buf) - 1)
250309124Sdim		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '%c'",
251309124Sdim		     line_no, *yytext);
252309124Sdim	*ptr++ = *yytext;
253309124Sdim}
254309124Sdim<charmap>[^ \t\n]+	{
255309124Sdim	strcat(map_name, "/");
256341825Sdim	strcat(map_name, yytext);
257309124Sdim	if((map_fp = fopen(map_name, "r")) == NULL)
258309124Sdim		err(EX_UNAVAILABLE, "can't open 'charmap' file %s",
259309124Sdim		    map_name);
260341825Sdim	save_no = line_no;
261309124Sdim	line_no = 1;
262309124Sdim	map_buf = yy_new_buffer(map_fp, YY_BUF_SIZE);
263309124Sdim	main_buf = YY_CURRENT_BUFFER;
264309124Sdim	yy_switch_to_buffer(map_buf);
265309124Sdim	ptr = buf;
266344779Sdim	BEGIN(defn);
267344779Sdim}
268309124Sdim<charmap>\n             {
269309124Sdim	errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u",
270309124Sdim	     line_no);
271309124Sdim}
272309124Sdim<charmap><<EOF>>        {
273309124Sdim	errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u",
274314564Sdim	     line_no);
275309124Sdim}
276314564Sdim<INITIAL,defn><<EOF>>                 {
277309124Sdim	if(map_fp != NULL) {
278309124Sdim		if (ptr != buf)
279314564Sdim			errx(EX_UNAVAILABLE, "premature EOF in the map near line %u of %s", line_no, map_name);
280314564Sdim		yy_switch_to_buffer(main_buf);
281309124Sdim		yy_delete_buffer(map_buf);
282309124Sdim		fclose(map_fp);
283309124Sdim		map_fp = NULL;
284296417Sdim		line_no = save_no;
285296417Sdim		BEGIN(INITIAL);
286296417Sdim	} else
287296417Sdim		yyterminate();
288296417Sdim}
289296417Sdim%%
290296417Sdim#ifdef FLEX_DEBUG
291296417Sdimmain()
292296417Sdim{
293296417Sdim	while(yylex())
294296417Sdim		;
295296417Sdim	return 0;
296296417Sdim}
297296417Sdim#endif /* FLEX_DEBUG */
298309124Sdim