scan.l revision 16020
1%x string name charmap
2%{
3/*-
4 * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
5 *		at Electronni Visti IA, Kiev, Ukraine.
6 *			All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $Id: scan.l,v 1.1.1.1 1995/02/17 17:29:50 ache Exp $
30 */
31
32#include <err.h>
33#include <unistd.h>
34#include <string.h>
35#include <sysexits.h>
36#include "collate.h"
37#include "parse.tab.h"
38
39int line_no = 1;
40u_char buf[STR_LEN], *ptr;
41FILE *map_fp;
42YY_BUFFER_STATE main_buf, map_buf;
43#ifdef FLEX_DEBUG
44YYSTYPE yylval;
45#endif /* FLEX_DEBUG */
46%}
47%%
48<INITIAL,charmap>[ \t]	;
49\"			{ ptr = buf; BEGIN(string); }
50\<			{ ptr = buf; BEGIN(name); }
51^#.*\n			line_no++;
52^\n			line_no++;
53\\\n			line_no++;
54\\t			{ yylval.ch = '\t'; return CHAR; }
55\\n			{ yylval.ch = '\n'; return CHAR; }
56\\b			{ yylval.ch = '\b'; return CHAR; }
57\\f			{ yylval.ch = '\f'; return CHAR; }
58\\v			{ yylval.ch = '\v'; return CHAR; }
59\\r			{ yylval.ch = '\r'; return CHAR; }
60\\a			{ yylval.ch = '\a'; return CHAR; }
61\\.			{ yylval.ch = yytext[1]; return CHAR; }
62<INITIAL,charmap>\n			{ line_no++; return '\n'; }
63[;,{}()]		return *yytext;
64substitute		return SUBSTITUTE;
65with			return WITH;
66order			return ORDER;
67charmap			BEGIN(charmap);
68;[ \t]*\.\.\.[ \t]*;		return RANGE;
69\\[0-7]{3}		{
70	u_int v;
71
72	sscanf(&yytext[1], "%o", &v);
73	yylval.ch = (u_char)v;
74	return CHAR;
75}
76\\x[0-9a-z]{2}		{
77	u_int v;
78
79	sscanf(&yytext[2], "%x", &v);
80	yylval.ch = (u_char)v;
81	return CHAR;
82}
83[^;,{}() \t\n"<]+	{
84	if(yyleng == 1) {
85		yylval.ch = *yytext;
86		return CHAR;
87	}
88	if(yyleng > STR_LEN - 1)
89		errx(EX_UNAVAILABLE, "chain buffer overflaw near line %u",
90		     line_no);
91	strcpy(yylval.str, yytext);
92	return CHAIN;
93}
94<name>\\\>		{
95	if(ptr >= buf + sizeof(buf) - 1)
96		errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u",
97		     line_no);
98	*ptr++ = '>';
99}
100<string>\\\"		{
101	if(ptr >= buf + sizeof(buf) - 1)
102		errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u",
103		     line_no);
104	*ptr++ = '"';
105}
106<name>\>		{
107	*ptr = '\0';
108	strcpy(yylval.str, buf);
109	BEGIN(INITIAL);
110	return NAME;
111}
112<string>\"		{
113	*ptr = '\0';
114	strcpy(yylval.str, buf);
115	BEGIN(INITIAL);
116	return STRING;
117}
118<name,string>.		{
119	if(ptr >= buf + sizeof(buf) - 1)
120		errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u",
121		     line_no);
122	*ptr++ = *yytext;
123}
124<name,string>\\t		{
125	if(ptr >= buf + sizeof(buf) - 1)
126		errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u",
127		     line_no);
128	*ptr++ = '\t';
129}
130<name,string>\\b		{
131	if(ptr >= buf + sizeof(buf) - 1)
132		errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u",
133		     line_no);
134	*ptr++ = '\b';
135}
136<name,string>\\f		{
137	if(ptr >= buf + sizeof(buf) - 1)
138		errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u",
139		     line_no);
140	*ptr++ = '\f';
141}
142<name,string>\\v		{
143	if(ptr >= buf + sizeof(buf) - 1)
144		errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u",
145		     line_no);
146	*ptr++ = '\v';
147}
148<name,string>\\n		{
149	if(ptr >= buf + sizeof(buf) - 1)
150		errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u",
151		     line_no);
152	*ptr++ = '\n';
153}
154<name,string>\\r		{
155	if(ptr >= buf + sizeof(buf) - 1)
156		errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u",
157		     line_no);
158	*ptr++ = '\r';
159}
160<name,string>\\a		{
161	if(ptr >= buf + sizeof(buf) - 1)
162		errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u",
163		     line_no);
164	*ptr++ = '\a';
165}
166<name,string><<EOF>>	{
167	errx(EX_UNAVAILABLE, "unterminated name/string near line %u", line_no);
168}
169<name,string>\\x[0-9a-f]{2}	{
170	u_int v;
171
172	sscanf(&yytext[2], "%x", &v);
173	*ptr++ = (u_char)v;
174}
175<name,string>\\[0-7]{3}	{
176	u_int v;
177
178	sscanf(&yytext[1], "%o", &v);
179	*ptr++ = (u_char)v;
180}
181<charmap>[^ \t\n]+	{
182	if((map_fp = fopen(yytext, "r")) == 0)
183		err(EX_UNAVAILABLE, "can't open charmap file %s near line %u",
184		    yytext, line_no);
185	map_buf = yy_new_buffer(map_fp, YY_BUF_SIZE);
186	main_buf = YY_CURRENT_BUFFER;
187	yy_switch_to_buffer(map_buf);
188	BEGIN(INITIAL);
189}
190<charmap><<EOF>>	{
191	errx(EX_UNAVAILABLE, "charmap file name expected near line %u",
192	     line_no);
193}
194<<EOF>>			{
195	if(map_fp) {
196		yy_switch_to_buffer(main_buf);
197		yy_delete_buffer(map_buf);
198		fclose(map_fp);
199		map_fp = 0;
200	}
201	else
202		yyterminate();
203}
204%%
205#ifdef FLEX_DEBUG
206main()
207{
208	while(yylex())
209		;
210	return 0;
211}
212#endif /* FLEX_DEBUG */
213