scan.l revision 87050
1239310Sdim%x string name charmap defn nchar subs subs2 2239310Sdim%{ 3353358Sdim/*- 4353358Sdim * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> 5353358Sdim * at Electronni Visti IA, Kiev, Ukraine. 6239310Sdim * All rights reserved. 7239310Sdim * 8239310Sdim * Redistribution and use in source and binary forms, with or without 9239310Sdim * modification, are permitted provided that the following conditions 10239310Sdim * are met: 11239310Sdim * 1. Redistributions of source code must retain the above copyright 12239310Sdim * notice, this list of conditions and the following disclaimer. 13321369Sdim * 2. Redistributions in binary form must reproduce the above copyright 14239310Sdim * notice, this list of conditions and the following disclaimer in the 15249423Sdim * documentation and/or other materials provided with the distribution. 16249423Sdim * 17280031Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 18288943Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19353358Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20314564Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 21314564Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22314564Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23239310Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24309124Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25288943Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26314564Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27249423Sdim * SUCH DAMAGE. 28239310Sdim * 29239310Sdim * $FreeBSD: head/usr.bin/colldef/scan.l 87050 2001-11-28 09:26:57Z ache $ 30239310Sdim */ 31321369Sdim 32239310Sdim#include <ctype.h> 33309124Sdim#include <err.h> 34314564Sdim#include <unistd.h> 35314564Sdim#include <string.h> 36314564Sdim#include <sysexits.h> 37239310Sdim#include "collate.h" 38239310Sdim#include "common.h" 39239310Sdim#include "y.tab.h" 40314564Sdim 41314564Sdimint line_no = 1, save_no, fromsubs; 42314564Sdimu_char buf[80], *ptr; 43314564SdimFILE *map_fp; 44314564SdimYY_BUFFER_STATE main_buf, map_buf; 45314564Sdim#ifdef FLEX_DEBUG 46309124SdimYYSTYPE yylval; 47335799Sdim#endif /* FLEX_DEBUG */ 48335799Sdim%} 49335799Sdim%% 50335799Sdim<INITIAL,charmap,nchar,subs,subs2>[ \t]+ ; 51335799Sdim<subs2>\" { ptr = buf; BEGIN(string); } 52335799Sdim<subs>\< { ptr = buf; fromsubs = 1; BEGIN(name); } 53335799Sdim<INITIAL>\< { ptr = buf; fromsubs = 0; BEGIN(name); } 54335799Sdim^#.*\n line_no++; 55341825Sdim^\n line_no++; 56341825Sdim<INITIAL>\\\n line_no++; 57341825Sdim<INITIAL,nchar,subs>\\t { yylval.ch = '\t'; return CHAR; } 58341825Sdim<INITIAL,nchar,subs>\\n { yylval.ch = '\n'; return CHAR; } 59341825Sdim<INITIAL,nchar,subs>\\b { yylval.ch = '\b'; return CHAR; } 60341825Sdim<INITIAL,nchar,subs>\\f { yylval.ch = '\f'; return CHAR; } 61249423Sdim<INITIAL,nchar,subs>\\v { yylval.ch = '\v'; return CHAR; } 62314564Sdim<INITIAL,nchar,subs>\\r { yylval.ch = '\r'; return CHAR; } 63309124Sdim<INITIAL,nchar,subs>\\a { yylval.ch = '\a'; return CHAR; } 64249423Sdim<INITIAL,nchar,subs>\\. { yylval.ch = yytext[1]; return CHAR; } 65251662Sdim<subs2>\n { 66288943Sdim line_no++; 67276479Sdim BEGIN(INITIAL); 68296417Sdim return '\n'; 69314564Sdim} 70288943Sdim<INITIAL,nchar>\n { 71344779Sdim line_no++; 72239310Sdim if (map_fp != NULL) { 73314564Sdim ptr = buf; 74314564Sdim BEGIN(defn); 75360784Sdim } 76239310Sdim return '\n'; 77314564Sdim} 78314564Sdim<INITIAL>[;,{}()] return *yytext; 79239310Sdim<INITIAL>substitute { BEGIN(subs); return SUBSTITUTE; } 80249423Sdim<subs>with { BEGIN(subs2); return WITH; } 81249423Sdim<INITIAL>order return ORDER; 82296417Sdim<INITIAL>charmap BEGIN(charmap); 83296417Sdim<INITIAL>;[ \t]*\.\.\.[ \t]*; return RANGE; 84309124Sdim<INITIAL,nchar,subs>\\[0-7]{3} { 85296417Sdim u_int v; 86296417Sdim 87296417Sdim sscanf(&yytext[1], "%o", &v); 88314564Sdim yylval.ch = (u_char)v; 89296417Sdim return CHAR; 90296417Sdim} 91344779Sdim<INITIAL,nchar,subs>\\x[0-9a-z]{2} { 92239310Sdim u_int v; 93239310Sdim 94341825Sdim sscanf(&yytext[2], "%x", &v); 95288943Sdim yylval.ch = (u_char)v; 96288943Sdim return CHAR; 97288943Sdim} 98288943Sdim<INITIAL>[^;,{}() \t\n"<]+ { 99341825Sdim if(yyleng == 1) { 100341825Sdim yylval.ch = *yytext; 101288943Sdim return CHAR; 102327952Sdim } 103288943Sdim if(yyleng > STR_LEN - 1) 104288943Sdim errx(EX_UNAVAILABLE, "chain buffer overflow near line %u", 105288943Sdim line_no); 106288943Sdim strcpy(yylval.str, yytext); 107288943Sdim return CHAIN; 108276479Sdim} 109276479Sdim<nchar,subs>. { 110309124Sdim yylval.ch = *yytext; 111327952Sdim return CHAR; 112276479Sdim} 113309124Sdim<defn>^#.*\n line_no++; 114309124Sdim<defn>[ \t]+ { 115341825Sdim if (ptr == buf) 116341825Sdim errx(EX_UNAVAILABLE, "map expected near line %u of %s", 117344779Sdim line_no, map_name); 118341825Sdim *ptr = '\0'; 119360784Sdim strcpy(yylval.str, buf); 120288943Sdim BEGIN(nchar); 121288943Sdim return DEFN; 122288943Sdim} 123288943Sdim<name>\/\/ { 124288943Sdim if(ptr >= buf + sizeof(buf) - 1) 125335799Sdim errx(EX_UNAVAILABLE, "name buffer overflow near line %u, character '/'", 126335799Sdim line_no); 127261991Sdim *ptr++ = '/'; 128261991Sdim} 129239310Sdim<name>\/\> { 130314564Sdim if(ptr >= buf + sizeof(buf) - 1) 131280031Sdim errx(EX_UNAVAILABLE, "name buffer overflow near line %u, character '>'", 132239310Sdim line_no); 133239310Sdim *ptr++ = '>'; 134288943Sdim} 135288943Sdim<string>\\\" { 136288943Sdim if(ptr >= buf + sizeof(buf) - 1) 137309124Sdim errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\"'", 138327952Sdim line_no); 139327952Sdim *ptr++ = '"'; 140249423Sdim} 141239310Sdim<name>\> { 142239310Sdim u_int i; 143239310Sdim 144288943Sdim if (ptr == buf) 145288943Sdim errx(EX_UNAVAILABLE, "non-empty name expected near line %u", 146288943Sdim line_no); 147309124Sdim *ptr = '\0'; 148327952Sdim for (i = 0; i <= UCHAR_MAX; i++) 149327952Sdim if (strcmp(charmap_table[i], buf) == 0) 150249423Sdim goto findit; 151239310Sdim errx(EX_UNAVAILABLE, "name <%s> not 'charmap'-defined near line %u", 152261991Sdim buf, line_no); 153314564Sdim findit: 154239310Sdim yylval.ch = i; 155239310Sdim if (fromsubs) 156321369Sdim BEGIN(subs); 157249423Sdim else 158239310Sdim BEGIN(INITIAL); 159239310Sdim return CHAR; 160239310Sdim} 161239310Sdim<string>\" { 162239310Sdim *ptr = '\0'; 163276479Sdim strcpy(yylval.str, buf); 164276479Sdim BEGIN(subs2); 165344779Sdim return STRING; 166280031Sdim} 167276479Sdim<name,defn>. { 168261991Sdim char *s = (map_fp != NULL) ? map_name : "input"; 169276479Sdim 170353358Sdim if (!isascii(*yytext) || !isprint(*yytext)) 171353358Sdim errx(EX_UNAVAILABLE, "non-ASCII or non-printable character 0x%02x not allowed in the map/name near line %u of %s", 172296417Sdim *yytext, line_no, s); 173353358Sdim if(ptr >= buf + sizeof(buf) - 1) 174353358Sdim errx(EX_UNAVAILABLE, "map/name buffer overflow near line %u of %s, character '%c'", 175353358Sdim line_no, s, *yytext); 176353358Sdim *ptr++ = *yytext; 177353358Sdim} 178353358Sdim<string>\\t { 179353358Sdim if(ptr >= buf + sizeof(buf) - 1) 180353358Sdim errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\t'", 181296417Sdim line_no); 182309124Sdim *ptr++ = '\t'; 183309124Sdim} 184296417Sdim<string>\\b { 185309124Sdim if(ptr >= buf + sizeof(buf) - 1) 186309124Sdim errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\b'", 187309124Sdim line_no); 188309124Sdim *ptr++ = '\b'; 189309124Sdim} 190309124Sdim<string>\\f { 191239310Sdim if(ptr >= buf + sizeof(buf) - 1) 192314564Sdim errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\f'", 193261991Sdim line_no); 194239310Sdim *ptr++ = '\f'; 195239310Sdim} 196321369Sdim<string>\\v { 197239310Sdim if(ptr >= buf + sizeof(buf) - 1) 198239310Sdim errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\v'", 199321369Sdim line_no); 200321369Sdim *ptr++ = '\v'; 201321369Sdim} 202321369Sdim<string>\\n { 203344779Sdim if(ptr >= buf + sizeof(buf) - 1) 204321369Sdim errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\n'", 205321369Sdim line_no); 206309124Sdim *ptr++ = '\n'; 207309124Sdim} 208327952Sdim<string>\\r { 209327952Sdim if(ptr >= buf + sizeof(buf) - 1) 210327952Sdim errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\r'", 211280031Sdim line_no); 212280031Sdim *ptr++ = '\r'; 213296417Sdim} 214296417Sdim<string>\\a { 215296417Sdim if(ptr >= buf + sizeof(buf) - 1) 216296417Sdim errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '\\a'", 217296417Sdim line_no); 218296417Sdim *ptr++ = '\a'; 219296417Sdim} 220309124Sdim<name,string,defn>\n { 221314564Sdim char *s = (map_fp != NULL) ? map_name : "input"; 222288943Sdim 223288943Sdim errx(EX_UNAVAILABLE, "unterminated map/name/string near line %u of %s", line_no, s); 224288943Sdim} 225321369Sdim<name,string,nchar><<EOF>> { 226309124Sdim char *s = (map_fp != NULL) ? map_name : "input"; 227296417Sdim 228309124Sdim errx(EX_UNAVAILABLE, "premature EOF in the name/string/char near line %u of %s", line_no, s); 229276479Sdim} 230296417Sdim<string>\\x[0-9a-f]{2} { 231288943Sdim u_int v; 232288943Sdim 233288943Sdim sscanf(&yytext[2], "%x", &v); 234288943Sdim *ptr++ = (u_char)v; 235288943Sdim} 236288943Sdim<string>\\[0-7]{3} { 237296417Sdim u_int v; 238288943Sdim 239288943Sdim sscanf(&yytext[1], "%o", &v); 240288943Sdim *ptr++ = (u_char)v; 241288943Sdim} 242288943Sdim<string>\\. { 243309124Sdim if(ptr >= buf + sizeof(buf) - 1) 244296417Sdim errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '%c'", 245309124Sdim line_no, yytext[1]); 246309124Sdim *ptr++ = yytext[1]; 247309124Sdim} 248309124Sdim<string>. { 249309124Sdim if(ptr >= buf + sizeof(buf) - 1) 250309124Sdim errx(EX_UNAVAILABLE, "string buffer overflow near line %u, character '%c'", 251309124Sdim line_no, *yytext); 252309124Sdim *ptr++ = *yytext; 253309124Sdim} 254309124Sdim<charmap>[^ \t\n]+ { 255309124Sdim strcat(map_name, "/"); 256341825Sdim strcat(map_name, yytext); 257309124Sdim if((map_fp = fopen(map_name, "r")) == NULL) 258309124Sdim err(EX_UNAVAILABLE, "can't open 'charmap' file %s", 259309124Sdim map_name); 260341825Sdim save_no = line_no; 261309124Sdim line_no = 1; 262309124Sdim map_buf = yy_new_buffer(map_fp, YY_BUF_SIZE); 263309124Sdim main_buf = YY_CURRENT_BUFFER; 264309124Sdim yy_switch_to_buffer(map_buf); 265309124Sdim ptr = buf; 266344779Sdim BEGIN(defn); 267344779Sdim} 268309124Sdim<charmap>\n { 269309124Sdim errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u", 270309124Sdim line_no); 271309124Sdim} 272309124Sdim<charmap><<EOF>> { 273309124Sdim errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u", 274314564Sdim line_no); 275309124Sdim} 276314564Sdim<INITIAL,defn><<EOF>> { 277309124Sdim if(map_fp != NULL) { 278309124Sdim if (ptr != buf) 279314564Sdim errx(EX_UNAVAILABLE, "premature EOF in the map near line %u of %s", line_no, map_name); 280314564Sdim yy_switch_to_buffer(main_buf); 281309124Sdim yy_delete_buffer(map_buf); 282309124Sdim fclose(map_fp); 283309124Sdim map_fp = NULL; 284296417Sdim line_no = save_no; 285296417Sdim BEGIN(INITIAL); 286296417Sdim } else 287296417Sdim yyterminate(); 288296417Sdim} 289296417Sdim%% 290296417Sdim#ifdef FLEX_DEBUG 291296417Sdimmain() 292296417Sdim{ 293296417Sdim while(yylex()) 294296417Sdim ; 295296417Sdim return 0; 296296417Sdim} 297296417Sdim#endif /* FLEX_DEBUG */ 298309124Sdim