PageRenderTime 24ms CodeModel.GetById 14ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 1ms

/usr.bin/colldef/scan.l

https://bitbucket.org/freebsd/freebsd-head/
LEX | 287 lines | 250 code | 11 blank | 26 comment | 0 complexity | 2a7d1884f5cf36d0b416b74572b81065 MD5 | raw file
  1%x string name charmap defn nchar subs subs2
  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
 30#include <sys/cdefs.h>
 31__FBSDID("$FreeBSD$");
 32
 33#include <sys/types.h>
 34#include <ctype.h>
 35#include <err.h>
 36#include <limits.h>
 37#include <unistd.h>
 38#include <string.h>
 39#include <sysexits.h>
 40#include "common.h"
 41#include "y.tab.h"
 42
 43int line_no = 1, save_no, fromsubs;
 44u_char buf[BUFSIZE], *ptr;
 45FILE *map_fp;
 46YY_BUFFER_STATE main_buf, map_buf;
 47#ifdef FLEX_DEBUG
 48YYSTYPE yylval;
 49#endif /* FLEX_DEBUG */
 50int yylex(void);
 51%}
 52%%
 53<INITIAL,charmap,nchar,subs,subs2>[ \t]+      ;
 54<subs2>\"               { ptr = buf; BEGIN(string); }
 55<subs>\<                { ptr = buf; fromsubs = 1; BEGIN(name); }
 56<INITIAL>\<             { ptr = buf; fromsubs = 0; BEGIN(name); }
 57^#.*\n			line_no++;
 58^\n			line_no++;
 59<INITIAL>\\\n           line_no++;
 60<INITIAL,nchar,subs>\\t      { yylval.ch = '\t'; return CHAR; }
 61<INITIAL,nchar,subs>\\n      { yylval.ch = '\n'; return CHAR; }
 62<INITIAL,nchar,subs>\\b      { yylval.ch = '\b'; return CHAR; }
 63<INITIAL,nchar,subs>\\f      { yylval.ch = '\f'; return CHAR; }
 64<INITIAL,nchar,subs>\\v      { yylval.ch = '\v'; return CHAR; }
 65<INITIAL,nchar,subs>\\r      { yylval.ch = '\r'; return CHAR; }
 66<INITIAL,nchar,subs>\\a      { yylval.ch = '\a'; return CHAR; }
 67<subs2>\n               {
 68	line_no++;
 69	BEGIN(INITIAL);
 70	return '\n';
 71}
 72<INITIAL,nchar>\n       {
 73	line_no++;
 74	if (map_fp != NULL) {
 75		ptr = buf;
 76		BEGIN(defn);
 77	}
 78	return '\n';
 79}
 80<INITIAL>[;,{}()]       return *yytext;
 81<INITIAL>substitute     { BEGIN(subs); return SUBSTITUTE; }
 82<subs>with              { BEGIN(subs2); return WITH; }
 83<INITIAL>order          return ORDER;
 84<INITIAL>charmap        BEGIN(charmap);
 85<INITIAL>;[ \t]*\.\.\.[ \t]*;   return RANGE;
 86<INITIAL,nchar,subs>\\[0-7]{3}       {
 87	u_int v;
 88
 89	sscanf(&yytext[1], "%o", &v);
 90	yylval.ch = (u_char)v;
 91	return CHAR;
 92}
 93<INITIAL,nchar,subs>\\x[0-9a-fA-F]{2}   {
 94	u_int v;
 95
 96	sscanf(&yytext[2], "%x", &v);
 97	yylval.ch = (u_char)v;
 98	return CHAR;
 99}
100<INITIAL,nchar,subs>\\. { yylval.ch = yytext[1]; return CHAR; }
101<INITIAL,nchar,subs>.   { yylval.ch = *yytext; return CHAR; }
102<defn>^#.*\n            line_no++;
103<defn>[ \t]+            {
104	if (ptr == buf)
105		errx(EX_UNAVAILABLE, "map expected near line %u of %s",
106		     line_no, map_name);
107	*ptr = '\0';
108	strcpy(yylval.str, buf);
109	BEGIN(nchar);
110	return DEFN;
111}
112<name>\/\/              {
113	if(ptr >= buf + sizeof(buf) - 1)
114		errx(EX_UNAVAILABLE, "name buffer overflow near line %u, character '/'",
115		     line_no);
116	*ptr++ = '/';
117}
118<name>\/\>              {
119	if(ptr >= buf + sizeof(buf) - 1)
120		errx(EX_UNAVAILABLE, "name buffer overflow near line %u, character '>'",
121		     line_no);
122	*ptr++ = '>';
123}
124<string>\\\"		{
125	if(ptr >= buf + sizeof(buf) - 1)
126		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\"'",
127		     line_no);
128	*ptr++ = '"';
129}
130<name>\>		{
131	u_int i;
132
133	if (ptr == buf)
134		errx(EX_UNAVAILABLE, "non-empty name expected near line %u",
135		     line_no);
136	*ptr = '\0';
137	for (i = 0; i <= UCHAR_MAX; i++) {
138		if (strcmp(charmap_table[i], buf) == 0)
139			goto findit;
140	}
141	errx(EX_UNAVAILABLE, "name <%s> not 'charmap'-defined near line %u",
142		buf, line_no);
143 findit:
144	yylval.ch = i;
145	if (fromsubs)
146		BEGIN(subs);
147	else
148		BEGIN(INITIAL);
149	return CHAR;
150}
151<string>\"		{
152	*ptr = '\0';
153	strcpy(yylval.str, buf);
154	BEGIN(subs2);
155	return STRING;
156}
157<name,defn>.            {
158	const char *s = (map_fp != NULL) ? map_name : "input";
159
160	if (!isascii(*yytext) || !isprint(*yytext))
161		errx(EX_UNAVAILABLE, "non-ASCII or non-printable character 0x%02x not allowed in the map/name near line %u of %s",
162		     *yytext, line_no, s);
163	if(ptr >= buf + sizeof(buf) - 1)
164		errx(EX_UNAVAILABLE, "map/name buffer overflow near line %u of %s, character '%c'",
165		     line_no, s, *yytext);
166	*ptr++ = *yytext;
167}
168<string>\\t             {
169	if(ptr >= buf + sizeof(buf) - 1)
170		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\t'",
171		     line_no);
172	*ptr++ = '\t';
173}
174<string>\\b             {
175	if(ptr >= buf + sizeof(buf) - 1)
176		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\b'",
177		     line_no);
178	*ptr++ = '\b';
179}
180<string>\\f             {
181	if(ptr >= buf + sizeof(buf) - 1)
182		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\f'",
183		     line_no);
184	*ptr++ = '\f';
185}
186<string>\\v             {
187	if(ptr >= buf + sizeof(buf) - 1)
188		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\v'",
189		     line_no);
190	*ptr++ = '\v';
191}
192<string>\\n             {
193	if(ptr >= buf + sizeof(buf) - 1)
194		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\n'",
195		     line_no);
196	*ptr++ = '\n';
197}
198<string>\\r             {
199	if(ptr >= buf + sizeof(buf) - 1)
200		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\r'",
201		     line_no);
202	*ptr++ = '\r';
203}
204<string>\\a             {
205	if(ptr >= buf + sizeof(buf) - 1)
206		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\a'",
207		     line_no);
208	*ptr++ = '\a';
209}
210<name,string,defn>\n            {
211	const char *s = (map_fp != NULL) ? map_name : "input";
212
213	errx(EX_UNAVAILABLE, "unterminated map/name/string near line %u of %s", line_no, s);
214}
215<name,string,nchar><<EOF>>      {
216	const char *s = (map_fp != NULL) ? map_name : "input";
217
218	errx(EX_UNAVAILABLE, "premature EOF in the name/string/char near line %u of %s", line_no, s);
219}
220<string>\\x[0-9a-f]{2}          {
221	u_int v;
222
223	sscanf(&yytext[2], "%x", &v);
224	*ptr++ = (u_char)v;
225}
226<string>\\[0-7]{3}              {
227	u_int v;
228
229	sscanf(&yytext[1], "%o", &v);
230	*ptr++ = (u_char)v;
231}
232<string>\\.             {
233	if(ptr >= buf + sizeof(buf) - 1)
234		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '%c'",
235		     line_no, yytext[1]);
236	*ptr++ = yytext[1];
237}
238<string>.               {
239	if(ptr >= buf + sizeof(buf) - 1)
240		errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '%c'",
241		     line_no, *yytext);
242	*ptr++ = *yytext;
243}
244<charmap>[^ \t\n]+	{
245	strcat(map_name, "/");
246	strcat(map_name, yytext);
247	if((map_fp = fopen(map_name, "r")) == NULL)
248		err(EX_UNAVAILABLE, "can't open 'charmap' file %s",
249		    map_name);
250	save_no = line_no;
251	line_no = 1;
252	map_buf = yy_new_buffer(map_fp, YY_BUF_SIZE);
253	main_buf = YY_CURRENT_BUFFER;
254	yy_switch_to_buffer(map_buf);
255	ptr = buf;
256	BEGIN(defn);
257}
258<charmap>\n             {
259	errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u",
260	     line_no);
261}
262<charmap><<EOF>>        {
263	errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u",
264	     line_no);
265}
266<INITIAL,defn><<EOF>>                 {
267	if(map_fp != NULL) {
268		if (ptr != buf)
269			errx(EX_UNAVAILABLE, "premature EOF in the map near line %u of %s", line_no, map_name);
270		yy_switch_to_buffer(main_buf);
271		yy_delete_buffer(map_buf);
272		fclose(map_fp);
273		map_fp = NULL;
274		line_no = save_no;
275		BEGIN(INITIAL);
276	} else
277		yyterminate();
278}
279%%
280#ifdef FLEX_DEBUG
281main()
282{
283	while(yylex())
284		;
285	return 0;
286}
287#endif /* FLEX_DEBUG */