scan.l revision 23012
138774Snsouch%x string name charmap defn nchar subs 293023Snsouch%{ 338774Snsouch/*- 438774Snsouch * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> 538774Snsouch * at Electronni Visti IA, Kiev, Ukraine. 638774Snsouch * All rights reserved. 738774Snsouch * 838774Snsouch * Redistribution and use in source and binary forms, with or without 938774Snsouch * modification, are permitted provided that the following conditions 1038774Snsouch * are met: 1138774Snsouch * 1. Redistributions of source code must retain the above copyright 1238774Snsouch * notice, this list of conditions and the following disclaimer. 1338774Snsouch * 2. Redistributions in binary form must reproduce the above copyright 1438774Snsouch * notice, this list of conditions and the following disclaimer in the 1538774Snsouch * documentation and/or other materials provided with the distribution. 1638774Snsouch * 1738774Snsouch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 1838774Snsouch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1938774Snsouch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2038774Snsouch * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 2138774Snsouch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2238774Snsouch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2338774Snsouch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2438774Snsouch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2538774Snsouch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2638774Snsouch * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27119418Sobrien * SUCH DAMAGE. 28119418Sobrien * 29119418Sobrien * $Id$ 3038774Snsouch */ 3138774Snsouch 3238774Snsouch#include <ctype.h> 3338774Snsouch#include <err.h> 3438774Snsouch#include <unistd.h> 3538774Snsouch#include <string.h> 3638774Snsouch#include <sysexits.h> 3738774Snsouch#include "collate.h" 3838774Snsouch#include "y.tab.h" 3938774Snsouch 4038774Snsouchint line_no = 1, save_no; 4138774Snsouchu_char buf[STR_LEN], *ptr; 4238774SnsouchFILE *map_fp; 4338774Snsouchextern char map_name[]; 4438774Snsouchextern u_char charmap_table[UCHAR_MAX + 1][STR_LEN]; 4538774SnsouchYY_BUFFER_STATE main_buf, map_buf; 4638774Snsouch#ifdef FLEX_DEBUG 4738774SnsouchYYSTYPE yylval; 4838774Snsouch#endif /* FLEX_DEBUG */ 4938774Snsouch%} 5038774Snsouch%% 5138774Snsouch<INITIAL,charmap,nchar,subs>[ \t]+ ; 5238774Snsouch<subs>\" { ptr = buf; BEGIN(string); } 5338774Snsouch<INITIAL>\< { ptr = buf; BEGIN(name); } 5438774Snsouch^#.*\n line_no++; 5538774Snsouch^\n line_no++; 5638774Snsouch<INITIAL>\\\n line_no++; 5738774Snsouch<INITIAL,nchar>\\t { yylval.ch = '\t'; return CHAR; } 5838774Snsouch<INITIAL,nchar>\\n { yylval.ch = '\n'; return CHAR; } 5938774Snsouch<INITIAL,nchar>\\b { yylval.ch = '\b'; return CHAR; } 6038774Snsouch<INITIAL,nchar>\\f { yylval.ch = '\f'; return CHAR; } 6138774Snsouch<INITIAL,nchar>\\v { yylval.ch = '\v'; return CHAR; } 6238774Snsouch<INITIAL,nchar>\\r { yylval.ch = '\r'; return CHAR; } 6338774Snsouch<INITIAL,nchar>\\a { yylval.ch = '\a'; return CHAR; } 6438774Snsouch<INITIAL,nchar>\\. { yylval.ch = yytext[1]; return CHAR; } 6538774Snsouch<subs>\n { 6638774Snsouch line_no++; 6793023Snsouch BEGIN(INITIAL); 6893023Snsouch return '\n'; 69123922Ssam} 7038774Snsouch<INITIAL,nchar>\n { 7138774Snsouch line_no++; 7238774Snsouch if (map_fp != NULL) { 73147256Sbrooks ptr = buf; 7438774Snsouch BEGIN(defn); 7538774Snsouch } 7638774Snsouch return '\n'; 7738774Snsouch} 7838774Snsouch<INITIAL>[;,{}()] return *yytext; 7938774Snsouch<INITIAL>substitute { BEGIN(subs); return SUBSTITUTE; } 8038774Snsouch<subs>with return WITH; 8138774Snsouch<INITIAL>order return ORDER; 8238774Snsouch<INITIAL>charmap BEGIN(charmap); 8338774Snsouch<INITIAL>;[ \t]*\.\.\.[ \t]*; return RANGE; 8438774Snsouch<INITIAL,nchar>\\[0-7]{3} { 8538774Snsouch u_int v; 8638774Snsouch 8738774Snsouch sscanf(&yytext[1], "%o", &v); 8838774Snsouch yylval.ch = (u_char)v; 8938774Snsouch return CHAR; 9038774Snsouch} 9138774Snsouch<INITIAL,nchar>\\x[0-9a-z]{2} { 9238774Snsouch u_int v; 9338774Snsouch 9438774Snsouch sscanf(&yytext[2], "%x", &v); 9538774Snsouch yylval.ch = (u_char)v; 9638774Snsouch return CHAR; 9738774Snsouch} 9838774Snsouch<INITIAL>[^;,{}() \t\n"<]+ { 9938774Snsouch if(yyleng == 1) { 10038774Snsouch yylval.ch = *yytext; 10138774Snsouch return CHAR; 10238774Snsouch } 10338774Snsouch if(yyleng > STR_LEN - 1) 10438774Snsouch errx(EX_UNAVAILABLE, "chain buffer overflaw near line %u", 10538774Snsouch line_no); 10638774Snsouch strcpy(yylval.str, yytext); 10738774Snsouch return CHAIN; 10838774Snsouch} 10938774Snsouch<nchar>. { 11038774Snsouch yylval.ch = *yytext; 11138774Snsouch return CHAR; 11238774Snsouch} 11338774Snsouch<defn>[ \t]+ { 11438774Snsouch if (ptr == buf) 11538774Snsouch errx(EX_UNAVAILABLE, "map expected near line %u of %s", 11638774Snsouch line_no, map_name); 11738774Snsouch *ptr = '\0'; 11838774Snsouch strcpy(yylval.str, buf); 11938774Snsouch BEGIN(nchar); 12038774Snsouch return DEFN; 12138774Snsouch} 12238774Snsouch<name>\/\/ { 12338774Snsouch if(ptr >= buf + sizeof(buf) - 1) 12438774Snsouch errx(EX_UNAVAILABLE, "name buffer overflaw near line %u, character '/'", 12538774Snsouch line_no); 12638774Snsouch *ptr++ = '/'; 12738774Snsouch} 12838774Snsouch<name>\/\> { 12938774Snsouch if(ptr >= buf + sizeof(buf) - 1) 13038774Snsouch errx(EX_UNAVAILABLE, "name buffer overflaw near line %u, character '>'", 13138774Snsouch line_no); 132147256Sbrooks *ptr++ = '>'; 13338774Snsouch} 134147256Sbrooks<string>\\\" { 135147256Sbrooks if(ptr >= buf + sizeof(buf) - 1) 136147256Sbrooks errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\"'", 137147256Sbrooks line_no); 138147256Sbrooks *ptr++ = '"'; 13993023Snsouch} 14038774Snsouch<name>\> { 14138774Snsouch u_int i; 142121816Sbrooks 14338774Snsouch if (ptr == buf) 144133690Srwatson errx(EX_UNAVAILABLE, "non-empty name expected near line %u", 145133690Srwatson line_no); 14638774Snsouch *ptr = '\0'; 14738774Snsouch for (i = 0; i <= UCHAR_MAX; i++) 14838774Snsouch if (strcmp(charmap_table[i], buf) == 0) 14938774Snsouch goto findit; 15038774Snsouch errx(EX_UNAVAILABLE, "name <%s> not 'charmap'-defined near line %u", 15138774Snsouch buf, line_no); 15238774Snsouch findit: 15338774Snsouch yylval.ch = i; 15438774Snsouch BEGIN(INITIAL); 15538774Snsouch return CHAR; 15638774Snsouch} 15738774Snsouch<string>\" { 15838774Snsouch *ptr = '\0'; 15938774Snsouch strcpy(yylval.str, buf); 16038774Snsouch BEGIN(subs); 16138774Snsouch return STRING; 16238774Snsouch} 16338774Snsouch<name,defn>. { 16438774Snsouch char *s = (map_fp != NULL) ? map_name : "input"; 165121816Sbrooks 16638774Snsouch if (!isascii(*yytext) || !isprint(*yytext)) 16738774Snsouch errx(EX_UNAVAILABLE, "non-ASCII or non-printable character 0x%02x not allowed in the map/name near line %u of %s", 16838774Snsouch *yytext, line_no, s); 16938774Snsouch if(ptr >= buf + sizeof(buf) - 1) 17038774Snsouch errx(EX_UNAVAILABLE, "map/name buffer overflaw near line %u of %s, character '%c'", 17138774Snsouch line_no, s, *yytext); 17238774Snsouch *ptr++ = *yytext; 17338774Snsouch} 17438774Snsouch<string>\\t { 17538774Snsouch if(ptr >= buf + sizeof(buf) - 1) 17638774Snsouch errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\t'", 17738774Snsouch line_no); 17838774Snsouch *ptr++ = '\t'; 17938774Snsouch} 18038774Snsouch<string>\\b { 18138774Snsouch if(ptr >= buf + sizeof(buf) - 1) 18238774Snsouch errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\b'", 18338774Snsouch line_no); 18438774Snsouch *ptr++ = '\b'; 18538774Snsouch} 18638774Snsouch<string>\\f { 18738774Snsouch if(ptr >= buf + sizeof(buf) - 1) 18838774Snsouch errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\f'", 18938774Snsouch line_no); 19038774Snsouch *ptr++ = '\f'; 19138774Snsouch} 19238774Snsouch<string>\\v { 19338774Snsouch if(ptr >= buf + sizeof(buf) - 1) 19438774Snsouch errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\v'", 19538774Snsouch line_no); 19638774Snsouch *ptr++ = '\v'; 19738774Snsouch} 19838774Snsouch<string>\\n { 199147256Sbrooks if(ptr >= buf + sizeof(buf) - 1) 200111119Simp errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\n'", 20138774Snsouch line_no); 20238774Snsouch *ptr++ = '\n'; 20338774Snsouch} 20438774Snsouch<string>\\r { 20538774Snsouch if(ptr >= buf + sizeof(buf) - 1) 206147256Sbrooks errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\r'", 207111119Simp line_no); 20838774Snsouch *ptr++ = '\r'; 20938774Snsouch} 21038774Snsouch<string>\\a { 21138774Snsouch if(ptr >= buf + sizeof(buf) - 1) 21238774Snsouch errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\a'", 21340782Snsouch line_no); 21438774Snsouch *ptr++ = '\a'; 21538774Snsouch} 21638774Snsouch<name,string,defn>\n { 21738774Snsouch char *s = (map_fp != NULL) ? map_name : "input"; 21838774Snsouch 21938774Snsouch errx(EX_UNAVAILABLE, "unterminated map/name/string near line %u of %s", line_no, s); 22038774Snsouch} 22138774Snsouch<name,string,nchar><<EOF>> { 22238774Snsouch char *s = (map_fp != NULL) ? map_name : "input"; 22338774Snsouch 22438774Snsouch errx(EX_UNAVAILABLE, "premature EOF in the name/string/char near line %u of %s", line_no, s); 22538774Snsouch} 22638774Snsouch<string>\\x[0-9a-f]{2} { 22738774Snsouch u_int v; 22838774Snsouch 22938774Snsouch sscanf(&yytext[2], "%x", &v); 23038774Snsouch *ptr++ = (u_char)v; 23138774Snsouch} 23238774Snsouch<string>\\[0-7]{3} { 23338774Snsouch u_int v; 23438774Snsouch 23538774Snsouch sscanf(&yytext[1], "%o", &v); 23638774Snsouch *ptr++ = (u_char)v; 23738774Snsouch} 23838774Snsouch<string>\\. { 23938774Snsouch if(ptr >= buf + sizeof(buf) - 1) 24038774Snsouch errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '%c'", 24138774Snsouch line_no, yytext[1]); 24238774Snsouch *ptr++ = yytext[1]; 24338774Snsouch} 24438774Snsouch<string>. { 24538774Snsouch if(ptr >= buf + sizeof(buf) - 1) 24638774Snsouch errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '%c'", 24738774Snsouch line_no, *yytext); 24838774Snsouch *ptr++ = *yytext; 24938774Snsouch} 25038774Snsouch<charmap>[^ \t\n]+ { 25138774Snsouch strcat(map_name, "/"); 252147256Sbrooks strcat(map_name, yytext); 25338774Snsouch if((map_fp = fopen(map_name, "r")) == NULL) 25438774Snsouch err(EX_UNAVAILABLE, "can't open 'charmap' file %s", 25538774Snsouch map_name); 256147256Sbrooks save_no = line_no; 25738774Snsouch line_no = 1; 25838774Snsouch map_buf = yy_new_buffer(map_fp, YY_BUF_SIZE); 25938774Snsouch main_buf = YY_CURRENT_BUFFER; 26038774Snsouch yy_switch_to_buffer(map_buf); 26138774Snsouch ptr = buf; 26238774Snsouch BEGIN(defn); 26338774Snsouch} 26438774Snsouch<charmap>\n { 26538774Snsouch errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u", 26638774Snsouch line_no); 26738774Snsouch} 26838774Snsouch<charmap><<EOF>> { 26938774Snsouch errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u", 27038774Snsouch line_no); 27138774Snsouch} 27238774Snsouch<INITIAL,defn><<EOF>> { 27338774Snsouch if(map_fp != NULL) { 27438774Snsouch if (ptr != buf) 27538774Snsouch errx(EX_UNAVAILABLE, "premature EOF in the map near line %u of %s", line_no, map_name); 27638774Snsouch yy_switch_to_buffer(main_buf); 27738774Snsouch yy_delete_buffer(map_buf); 27838774Snsouch fclose(map_fp); 27938774Snsouch map_fp = NULL; 28038774Snsouch line_no = save_no; 28138774Snsouch BEGIN(INITIAL); 28238774Snsouch } else 28338774Snsouch yyterminate(); 28438774Snsouch} 28538774Snsouch%% 28638774Snsouch#ifdef FLEX_DEBUG 28738774Snsouchmain() 28838774Snsouch{ 28938774Snsouch while(yylex()) 29038774Snsouch ; 29138774Snsouch return 0; 29238774Snsouch} 29338774Snsouch#endif /* FLEX_DEBUG */ 29438774Snsouch