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