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$"); 3287243Smarkm 33175038Simp#include <sys/types.h> 3418950Sache#include <ctype.h> 356527Sache#include <err.h> 36101867Sache#include <limits.h> 376527Sache#include <unistd.h> 386527Sache#include <string.h> 396527Sache#include <sysexits.h> 4087012Sache#include "common.h" 4116073Sphk#include "y.tab.h" 426527Sache 4343967Sacheint line_no = 1, save_no, fromsubs; 4487052Sacheu_char buf[BUFSIZE], *ptr; 456527SacheFILE *map_fp; 466527SacheYY_BUFFER_STATE main_buf, map_buf; 476527Sache#ifdef FLEX_DEBUG 486527SacheYYSTYPE yylval; 496527Sache#endif /* FLEX_DEBUG */ 5087243Smarkmint yylex(void); 516527Sache%} 526527Sache%% 5343967Sache<INITIAL,charmap,nchar,subs,subs2>[ \t]+ ; 5443967Sache<subs2>\" { ptr = buf; BEGIN(string); } 5543967Sache<subs>\< { ptr = buf; fromsubs = 1; BEGIN(name); } 5643967Sache<INITIAL>\< { ptr = buf; fromsubs = 0; BEGIN(name); } 576527Sache^#.*\n line_no++; 586527Sache^\n line_no++; 5918950Sache<INITIAL>\\\n line_no++; 6043967Sache<INITIAL,nchar,subs>\\t { yylval.ch = '\t'; return CHAR; } 6143967Sache<INITIAL,nchar,subs>\\n { yylval.ch = '\n'; return CHAR; } 6243967Sache<INITIAL,nchar,subs>\\b { yylval.ch = '\b'; return CHAR; } 6343967Sache<INITIAL,nchar,subs>\\f { yylval.ch = '\f'; return CHAR; } 6443967Sache<INITIAL,nchar,subs>\\v { yylval.ch = '\v'; return CHAR; } 6543967Sache<INITIAL,nchar,subs>\\r { yylval.ch = '\r'; return CHAR; } 6643967Sache<INITIAL,nchar,subs>\\a { yylval.ch = '\a'; 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} 93102299Sache<INITIAL,nchar,subs>\\x[0-9a-fA-F]{2} { 946527Sache u_int v; 956527Sache 966527Sache sscanf(&yytext[2], "%x", &v); 976527Sache yylval.ch = (u_char)v; 986527Sache return CHAR; 996527Sache} 100102299Sache<INITIAL,nchar,subs>\\. { yylval.ch = yytext[1]; return CHAR; } 101102299Sache<INITIAL,nchar,subs>. { yylval.ch = *yytext; return CHAR; } 10251890Sache<defn>^#.*\n line_no++; 10318950Sache<defn>[ \t]+ { 10418950Sache if (ptr == buf) 10518950Sache errx(EX_UNAVAILABLE, "map expected near line %u of %s", 10618950Sache line_no, map_name); 10718950Sache *ptr = '\0'; 10818950Sache strcpy(yylval.str, buf); 10918950Sache BEGIN(nchar); 11018950Sache return DEFN; 11118950Sache} 11218950Sache<name>\/\/ { 1136527Sache if(ptr >= buf + sizeof(buf) - 1) 11443940Sache errx(EX_UNAVAILABLE, "name buffer overflow near line %u, character '/'", 1156527Sache line_no); 11618950Sache *ptr++ = '/'; 11718950Sache} 11818950Sache<name>\/\> { 11918950Sache if(ptr >= buf + sizeof(buf) - 1) 12043940Sache errx(EX_UNAVAILABLE, "name buffer overflow near line %u, character '>'", 12118950Sache line_no); 1226527Sache *ptr++ = '>'; 1236527Sache} 1246527Sache<string>\\\" { 1256527Sache if(ptr >= buf + sizeof(buf) - 1) 12643940Sache errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\"'", 1276527Sache line_no); 1286527Sache *ptr++ = '"'; 1296527Sache} 1306527Sache<name>\> { 13118955Sache u_int i; 13218955Sache 13318950Sache if (ptr == buf) 13418955Sache errx(EX_UNAVAILABLE, "non-empty name expected near line %u", 13518950Sache line_no); 1366527Sache *ptr = '\0'; 13787052Sache for (i = 0; i <= UCHAR_MAX; i++) { 13818955Sache if (strcmp(charmap_table[i], buf) == 0) 13918955Sache goto findit; 14087052Sache } 14118955Sache errx(EX_UNAVAILABLE, "name <%s> not 'charmap'-defined near line %u", 14218955Sache buf, line_no); 14387052Sache findit: 14418955Sache yylval.ch = i; 14543967Sache if (fromsubs) 14643967Sache BEGIN(subs); 14743967Sache else 14843967Sache BEGIN(INITIAL); 14918955Sache return CHAR; 1506527Sache} 1516527Sache<string>\" { 1526527Sache *ptr = '\0'; 1536527Sache strcpy(yylval.str, buf); 15443967Sache BEGIN(subs2); 1556527Sache return STRING; 1566527Sache} 15718950Sache<name,defn>. { 15887243Smarkm const char *s = (map_fp != NULL) ? map_name : "input"; 15918950Sache 16018950Sache if (!isascii(*yytext) || !isprint(*yytext)) 16118950Sache errx(EX_UNAVAILABLE, "non-ASCII or non-printable character 0x%02x not allowed in the map/name near line %u of %s", 16218950Sache *yytext, line_no, s); 1636527Sache if(ptr >= buf + sizeof(buf) - 1) 16443940Sache errx(EX_UNAVAILABLE, "map/name buffer overflow near line %u of %s, character '%c'", 16518950Sache line_no, s, *yytext); 1666527Sache *ptr++ = *yytext; 1676527Sache} 16818950Sache<string>\\t { 1696527Sache if(ptr >= buf + sizeof(buf) - 1) 17043940Sache errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\t'", 1716527Sache line_no); 1726527Sache *ptr++ = '\t'; 1736527Sache} 17418950Sache<string>\\b { 1756527Sache if(ptr >= buf + sizeof(buf) - 1) 17643940Sache errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\b'", 1776527Sache line_no); 1786527Sache *ptr++ = '\b'; 1796527Sache} 18018950Sache<string>\\f { 1816527Sache if(ptr >= buf + sizeof(buf) - 1) 18243940Sache errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\f'", 1836527Sache line_no); 1846527Sache *ptr++ = '\f'; 1856527Sache} 18618950Sache<string>\\v { 1876527Sache if(ptr >= buf + sizeof(buf) - 1) 18843940Sache errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\v'", 1896527Sache line_no); 1906527Sache *ptr++ = '\v'; 1916527Sache} 19218950Sache<string>\\n { 1936527Sache if(ptr >= buf + sizeof(buf) - 1) 19443940Sache errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\n'", 1956527Sache line_no); 1966527Sache *ptr++ = '\n'; 1976527Sache} 19818950Sache<string>\\r { 1996527Sache if(ptr >= buf + sizeof(buf) - 1) 20043940Sache errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\r'", 2016527Sache line_no); 2026527Sache *ptr++ = '\r'; 2036527Sache} 20418950Sache<string>\\a { 2056527Sache if(ptr >= buf + sizeof(buf) - 1) 20643940Sache errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\a'", 2076527Sache line_no); 2086527Sache *ptr++ = '\a'; 2096527Sache} 21018950Sache<name,string,defn>\n { 21187243Smarkm const char *s = (map_fp != NULL) ? map_name : "input"; 21218950Sache 21318950Sache errx(EX_UNAVAILABLE, "unterminated map/name/string near line %u of %s", line_no, s); 2146527Sache} 21518950Sache<name,string,nchar><<EOF>> { 21687243Smarkm const char *s = (map_fp != NULL) ? map_name : "input"; 21718950Sache 21818950Sache errx(EX_UNAVAILABLE, "premature EOF in the name/string/char near line %u of %s", line_no, s); 21918950Sache} 22018950Sache<string>\\x[0-9a-f]{2} { 2216527Sache u_int v; 2226527Sache 2236527Sache sscanf(&yytext[2], "%x", &v); 2246527Sache *ptr++ = (u_char)v; 2256527Sache} 22618950Sache<string>\\[0-7]{3} { 2276527Sache u_int v; 2286527Sache 2296527Sache sscanf(&yytext[1], "%o", &v); 2306527Sache *ptr++ = (u_char)v; 2316527Sache} 23218950Sache<string>\\. { 23318950Sache if(ptr >= buf + sizeof(buf) - 1) 23443940Sache errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '%c'", 23518950Sache line_no, yytext[1]); 23618950Sache *ptr++ = yytext[1]; 23718950Sache} 23818950Sache<string>. { 23918950Sache if(ptr >= buf + sizeof(buf) - 1) 24043940Sache errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '%c'", 24118950Sache line_no, *yytext); 24218950Sache *ptr++ = *yytext; 24318950Sache} 2446527Sache<charmap>[^ \t\n]+ { 24518950Sache strcat(map_name, "/"); 24618950Sache strcat(map_name, yytext); 24718950Sache if((map_fp = fopen(map_name, "r")) == NULL) 24818950Sache err(EX_UNAVAILABLE, "can't open 'charmap' file %s", 24918950Sache map_name); 25018950Sache save_no = line_no; 25118950Sache line_no = 1; 2526527Sache map_buf = yy_new_buffer(map_fp, YY_BUF_SIZE); 2536527Sache main_buf = YY_CURRENT_BUFFER; 2546527Sache yy_switch_to_buffer(map_buf); 25518950Sache ptr = buf; 25618950Sache BEGIN(defn); 2576527Sache} 25818950Sache<charmap>\n { 25918950Sache errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u", 2606527Sache line_no); 2616527Sache} 26218950Sache<charmap><<EOF>> { 26318950Sache errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u", 26418950Sache line_no); 26518950Sache} 26618950Sache<INITIAL,defn><<EOF>> { 26718950Sache if(map_fp != NULL) { 26818950Sache if (ptr != buf) 26918950Sache errx(EX_UNAVAILABLE, "premature EOF in the map near line %u of %s", line_no, map_name); 2706527Sache yy_switch_to_buffer(main_buf); 2716527Sache yy_delete_buffer(map_buf); 2726527Sache fclose(map_fp); 27318950Sache map_fp = NULL; 27418950Sache line_no = save_no; 27518950Sache BEGIN(INITIAL); 27618950Sache } else 2776527Sache yyterminate(); 2786527Sache} 2796527Sache%% 2806527Sache#ifdef FLEX_DEBUG 2816527Sachemain() 2826527Sache{ 2836527Sache while(yylex()) 2846527Sache ; 2856527Sache return 0; 2866527Sache} 2876527Sache#endif /* FLEX_DEBUG */ 288