1129468Sru%x string name charmap defn nchar subs subs2 2129468Sru%{ 3147647Shmp/*- 4246751Sglebius * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> 5137872Srwatson * at Electronni Visti IA, Kiev, Ukraine. 6129468Sru * All rights reserved. 7137872Srwatson * 8129468Sru * Redistribution and use in source and binary forms, with or without 9129468Sru * modification, are permitted provided that the following conditions 10129468Sru * are met: 11129468Sru * 1. Redistributions of source code must retain the above copyright 12129468Sru * notice, this list of conditions and the following disclaimer. 13129468Sru * 2. Redistributions in binary form must reproduce the above copyright 14129468Sru * notice, this list of conditions and the following disclaimer in the 15129468Sru * documentation and/or other materials provided with the distribution. 16129468Sru * 17129468Sru * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 18129468Sru * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19129468Sru * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20129468Sru * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 21129468Sru * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22129468Sru * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23175253Smaxim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24129468Sru * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25129468Sru * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26129468Sru * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27129468Sru * SUCH DAMAGE. 28129468Sru */ 29129468Sru 30129468Sru#include <sys/cdefs.h> 31129468Sru__FBSDID("$FreeBSD$"); 32231564Sed 33129468Sru#include <sys/types.h> 34129468Sru#include <ctype.h> 35129468Sru#include <err.h> 36129468Sru#include <limits.h> 37129468Sru#include <unistd.h> 38129468Sru#include <string.h> 39129468Sru#include <sysexits.h> 40129468Sru#include "common.h" 41129468Sru#include "y.tab.h" 42129468Sru 43129468Sruint line_no = 1, save_no, fromsubs; 44129468Sruu_char buf[BUFSIZE], *ptr; 45129468SruFILE *map_fp; 46129468SruYY_BUFFER_STATE main_buf, map_buf; 47129468Sru#ifdef FLEX_DEBUG 48129468SruYYSTYPE yylval; 49129468Sru#endif /* FLEX_DEBUG */ 50129468Sruint yylex(void); 51129468Sru%} 52129468Sru%% 53129468Sru<INITIAL,charmap,nchar,subs,subs2>[ \t]+ ; 54231564Sed<subs2>\" { ptr = buf; BEGIN(string); } 55129468Sru<subs>\< { ptr = buf; fromsubs = 1; BEGIN(name); } 56129468Sru<INITIAL>\< { ptr = buf; fromsubs = 0; BEGIN(name); } 57129468Sru^#.*\n line_no++; 58129468Sru^\n line_no++; 59129468Sru<INITIAL>\\\n line_no++; 60129468Sru<INITIAL,nchar,subs>\\t { yylval.ch = '\t'; return CHAR; } 61129468Sru<INITIAL,nchar,subs>\\n { yylval.ch = '\n'; return CHAR; } 62137872Srwatson<INITIAL,nchar,subs>\\b { yylval.ch = '\b'; return CHAR; } 63137872Srwatson<INITIAL,nchar,subs>\\f { yylval.ch = '\f'; return CHAR; } 64137872Srwatson<INITIAL,nchar,subs>\\v { yylval.ch = '\v'; return CHAR; } 65137872Srwatson<INITIAL,nchar,subs>\\r { yylval.ch = '\r'; return CHAR; } 66137872Srwatson<INITIAL,nchar,subs>\\a { yylval.ch = '\a'; return CHAR; } 67137872Srwatson<subs2>\n { 68137872Srwatson line_no++; 69137953Srwatson BEGIN(INITIAL); 70137872Srwatson return '\n'; 71137872Srwatson} 72175247Smaxim<INITIAL,nchar>\n { 73175247Smaxim line_no++; 74137872Srwatson if (map_fp != NULL) { 75137872Srwatson ptr = buf; 76137872Srwatson BEGIN(defn); 77137872Srwatson } 78137872Srwatson return '\n'; 79137872Srwatson} 80137872Srwatson<INITIAL>[;,{}()] return *yytext; 81137953Srwatson<INITIAL>substitute { BEGIN(subs); return SUBSTITUTE; } 82137953Srwatson<subs>with { BEGIN(subs2); return WITH; } 83137953Srwatson<INITIAL>order return ORDER; 84137953Srwatson<INITIAL>charmap BEGIN(charmap); 85137872Srwatson<INITIAL>;[ \t]*\.\.\.[ \t]*; return RANGE; 86137872Srwatson<INITIAL,nchar,subs>\\[0-7]{3} { 87137872Srwatson u_int v; 88137872Srwatson 89129468Sru sscanf(&yytext[1], "%o", &v); 90129468Sru yylval.ch = (u_char)v; 91129468Sru return CHAR; 92129468Sru} 93129468Sru<INITIAL,nchar,subs>\\x[0-9a-fA-F]{2} { 94129468Sru u_int v; 95129468Sru 96129468Sru sscanf(&yytext[2], "%x", &v); 97129468Sru yylval.ch = (u_char)v; 98129468Sru return CHAR; 99129468Sru} 100129468Sru<INITIAL,nchar,subs>\\. { yylval.ch = yytext[1]; return CHAR; } 101129468Sru<INITIAL,nchar,subs>. { yylval.ch = *yytext; return CHAR; } 102129468Sru<defn>^#.*\n line_no++; 103231564Sed<defn>[ \t]+ { 104231564Sed if (ptr == buf) 105231564Sed errx(EX_UNAVAILABLE, "map expected near line %u of %s", 106129468Sru line_no, map_name); 107129468Sru *ptr = '\0'; 108129468Sru strcpy(yylval.str, buf); 109129468Sru BEGIN(nchar); 110129468Sru return DEFN; 111129468Sru} 112129468Sru<name>\/\/ { 113129468Sru if(ptr >= buf + sizeof(buf) - 1) 114129468Sru errx(EX_UNAVAILABLE, "name buffer overflow near line %u, character '/'", 115129468Sru line_no); 116129468Sru *ptr++ = '/'; 117129468Sru} 118129468Sru<name>\/\> { 119129468Sru if(ptr >= buf + sizeof(buf) - 1) 120129468Sru errx(EX_UNAVAILABLE, "name buffer overflow near line %u, character '>'", 121129468Sru line_no); 122129468Sru *ptr++ = '>'; 123136347Sglebius} 124140140Sru<string>\\\" { 125129468Sru if(ptr >= buf + sizeof(buf) - 1) 126129468Sru errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\"'", 127129468Sru line_no); 128129468Sru *ptr++ = '"'; 129129468Sru} 130129468Sru<name>\> { 131129468Sru u_int i; 132129468Sru 133129468Sru if (ptr == buf) 134129468Sru errx(EX_UNAVAILABLE, "non-empty name expected near line %u", 135129468Sru line_no); 136129468Sru *ptr = '\0'; 137129468Sru for (i = 0; i <= UCHAR_MAX; i++) { 138129468Sru if (strcmp(charmap_table[i], buf) == 0) 139129468Sru goto findit; 140129468Sru } 141129468Sru errx(EX_UNAVAILABLE, "name <%s> not 'charmap'-defined near line %u", 142129468Sru buf, line_no); 143129468Sru findit: 144129468Sru yylval.ch = i; 145129468Sru if (fromsubs) 146129468Sru BEGIN(subs); 147129468Sru else 148129468Sru BEGIN(INITIAL); 149129468Sru return CHAR; 150129468Sru} 151129468Sru<string>\" { 152129468Sru *ptr = '\0'; 153129468Sru strcpy(yylval.str, buf); 154129468Sru BEGIN(subs2); 155129468Sru return STRING; 156129468Sru} 157129468Sru<name,defn>. { 158129468Sru const char *s = (map_fp != NULL) ? map_name : "input"; 159129468Sru 160129468Sru if (!isascii(*yytext) || !isprint(*yytext)) 161129468Sru errx(EX_UNAVAILABLE, "non-ASCII or non-printable character 0x%02x not allowed in the map/name near line %u of %s", 162129468Sru *yytext, line_no, s); 163129468Sru if(ptr >= buf + sizeof(buf) - 1) 164129468Sru errx(EX_UNAVAILABLE, "map/name buffer overflow near line %u of %s, character '%c'", 165129468Sru line_no, s, *yytext); 166129468Sru *ptr++ = *yytext; 167129468Sru} 168129468Sru<string>\\t { 169129468Sru if(ptr >= buf + sizeof(buf) - 1) 170129468Sru errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\t'", 171129468Sru line_no); 172129468Sru *ptr++ = '\t'; 173129468Sru} 174129468Sru<string>\\b { 175129468Sru if(ptr >= buf + sizeof(buf) - 1) 176129468Sru errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\b'", 177129468Sru line_no); 178129468Sru *ptr++ = '\b'; 179129468Sru} 180129468Sru<string>\\f { 181129468Sru if(ptr >= buf + sizeof(buf) - 1) 182129468Sru errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\f'", 183129468Sru line_no); 184129468Sru *ptr++ = '\f'; 185129468Sru} 186129468Sru<string>\\v { 187129468Sru if(ptr >= buf + sizeof(buf) - 1) 188129468Sru errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\v'", 189129468Sru line_no); 190129468Sru *ptr++ = '\v'; 191129468Sru} 192129468Sru<string>\\n { 193129468Sru if(ptr >= buf + sizeof(buf) - 1) 194129468Sru errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\n'", 195129468Sru line_no); 196129468Sru *ptr++ = '\n'; 197129468Sru} 198129468Sru<string>\\r { 199129468Sru if(ptr >= buf + sizeof(buf) - 1) 200129468Sru errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\r'", 201129468Sru line_no); 202129468Sru *ptr++ = '\r'; 203129468Sru} 204129468Sru<string>\\a { 205129468Sru if(ptr >= buf + sizeof(buf) - 1) 206129468Sru errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\a'", 207129468Sru line_no); 208129468Sru *ptr++ = '\a'; 209129468Sru} 210129468Sru<name,string,defn>\n { 211129468Sru const char *s = (map_fp != NULL) ? map_name : "input"; 212129468Sru 213129468Sru errx(EX_UNAVAILABLE, "unterminated map/name/string near line %u of %s", line_no, s); 214129468Sru} 215129468Sru<name,string,nchar><<EOF>> { 216129468Sru const char *s = (map_fp != NULL) ? map_name : "input"; 217129468Sru 218129468Sru errx(EX_UNAVAILABLE, "premature EOF in the name/string/char near line %u of %s", line_no, s); 219129468Sru} 220129468Sru<string>\\x[0-9a-f]{2} { 221129468Sru u_int v; 222129468Sru 223129468Sru sscanf(&yytext[2], "%x", &v); 224129468Sru *ptr++ = (u_char)v; 225129468Sru} 226136347Sglebius<string>\\[0-7]{3} { 227136347Sglebius u_int v; 228136347Sglebius 229140140Sru sscanf(&yytext[1], "%o", &v); 230140140Sru *ptr++ = (u_char)v; 231140140Sru} 232136347Sglebius<string>\\. { 233129468Sru if(ptr >= buf + sizeof(buf) - 1) 234129468Sru errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '%c'", 235129468Sru line_no, yytext[1]); 236129468Sru *ptr++ = yytext[1]; 237129468Sru} 238129468Sru<string>. { 239129468Sru if(ptr >= buf + sizeof(buf) - 1) 240129468Sru errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '%c'", 241129468Sru line_no, *yytext); 242129468Sru *ptr++ = *yytext; 243129468Sru} 244129468Sru<charmap>[^ \t\n]+ { 245129468Sru strcat(map_name, "/"); 246129468Sru strcat(map_name, yytext); 247129468Sru if((map_fp = fopen(map_name, "r")) == NULL) 248129468Sru err(EX_UNAVAILABLE, "can't open 'charmap' file %s", 249129468Sru map_name); 250129468Sru save_no = line_no; 251129468Sru line_no = 1; 252129468Sru map_buf = yy_new_buffer(map_fp, YY_BUF_SIZE); 253129468Sru main_buf = YY_CURRENT_BUFFER; 254129468Sru yy_switch_to_buffer(map_buf); 255129468Sru ptr = buf; 256129468Sru BEGIN(defn); 257129468Sru} 258129468Sru<charmap>\n { 259129468Sru errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u", 260129468Sru line_no); 261129468Sru} 262129468Sru<charmap><<EOF>> { 263129468Sru errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u", 264129468Sru line_no); 265129468Sru} 266129468Sru<INITIAL,defn><<EOF>> { 267129468Sru if(map_fp != NULL) { 268129468Sru if (ptr != buf) 269129468Sru errx(EX_UNAVAILABLE, "premature EOF in the map near line %u of %s", line_no, map_name); 270129468Sru yy_switch_to_buffer(main_buf); 271129468Sru yy_delete_buffer(map_buf); 272129468Sru fclose(map_fp); 273129468Sru map_fp = NULL; 274129468Sru line_no = save_no; 275129468Sru BEGIN(INITIAL); 276129468Sru } else 277129468Sru yyterminate(); 278129468Sru} 279129468Sru%% 280129468Sru#ifdef FLEX_DEBUG 281129468Srumain() 282129468Sru{ 283129468Sru while(yylex()) 284129468Sru ; 285129468Sru return 0; 286129468Sru} 287#endif /* FLEX_DEBUG */ 288