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