diff options
author | Andrey A. Chernov <ache@FreeBSD.org> | 1995-02-17 17:29:50 +0000 |
---|---|---|
committer | Andrey A. Chernov <ache@FreeBSD.org> | 1995-02-17 17:29:50 +0000 |
commit | a1c128ae2aacbd0f00ec7bbe7985418b26019bd2 (patch) | |
tree | 8db69da592d9ada09b0fbc5e436d8761f64ce4aa /usr.bin | |
parent | 3453c5d5dbf1833a8d2e208c460e87efe827635b (diff) | |
download | src-a1c128ae2aacbd0f00ec7bbe7985418b26019bd2.tar.gz src-a1c128ae2aacbd0f00ec7bbe7985418b26019bd2.zip |
collate tables compiler
Submitted by: alex@elvisti.kiev.ua
Notes
Notes:
svn path=/cvs2svn/branches/alex/; revision=6527
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/colldef/Makefile | 22 | ||||
-rw-r--r-- | usr.bin/colldef/colldef.1 | 194 | ||||
-rw-r--r-- | usr.bin/colldef/data/lt_LN.ISO8859-1 | 16 | ||||
-rw-r--r-- | usr.bin/colldef/data/lt_LN.ISO_8859-1 | 16 | ||||
-rw-r--r-- | usr.bin/colldef/data/ru_SU.KOI8-R | 6 | ||||
-rw-r--r-- | usr.bin/colldef/parse.y | 248 | ||||
-rw-r--r-- | usr.bin/colldef/scan.l | 212 |
7 files changed, 714 insertions, 0 deletions
diff --git a/usr.bin/colldef/Makefile b/usr.bin/colldef/Makefile new file mode 100644 index 000000000000..590c455af7f5 --- /dev/null +++ b/usr.bin/colldef/Makefile @@ -0,0 +1,22 @@ +# $Id: Makefile,v 1.2 1995/01/23 08:56:06 alex Exp alex $ + +PROG = colldef +LFLAGS = -8 -i +YFLAGS = -d +CFLAGS += -I. -I${.CURDIR}/../../lib/libc/locale +SRCS = parse.y scan.l +LDADD = -ll +DPADD = ${LIBL} +CLEANFILES = y.tab.[ch] lex.yy.c + +LOCALES= ru_SU.KOI8-R lt_LN.ISO8859-1 +LOCALEDIR= ${DESTDIR}/usr/share/locale + +afterinstall: + for l in ${LOCALES}; do \ + colldef -o ${LOCALEDIR}/$$l/LC_COLLATE ${.CURDIR}/data/$$l; \ + chown ${BINOWN}.${BINGRP} ${LOCALEDIR}/$$l/LC_COLLATE; \ + chmod 644 ${LOCALEDIR}/$$l/LC_COLLATE; \ + done + +.include <bsd.prog.mk> diff --git a/usr.bin/colldef/colldef.1 b/usr.bin/colldef/colldef.1 new file mode 100644 index 000000000000..5cb3b3a3438f --- /dev/null +++ b/usr.bin/colldef/colldef.1 @@ -0,0 +1,194 @@ +.\" Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> +.\" at Electronni Visti IA, Kiev, Ukraine. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd January, 27 1995 +.Dt COLLDEF 1 +.Os +.Sh NAME +.Nm colldef +.Nd convert collation sequence source definition +.Sh SYNOPSIS +.Nm colldef +.Ar [-o out_file] [filename] +.Sh DESCRIPTION +.Ar colldef +converts a collation sequence source definition +into a format usable by the +.Fn strxfrm +and +.Fn strcoll +functions. It is used to define the many ways in which +strings can be ordered and collated. +.Fn strxfrm +transforms +its first argument and places the result in its second +argument. The transformed string is such that it can be +correctly ordered with other transformed strings by using +.Fn strcmp , +.Fn strncmp , +or +.Fn memcmp . +.Fn strcoll +transforms its arguments and does a +comparison. +.Pp +.Ar colldef +reads the collation sequence source definition +from the standard input and stores the converted definition in filename. +The output file produced contains the +database with collating sequence information in a form +usable by system commands and routines. +.Pp +The collation sequence definition specifies a set of collating elements and +the rules defining how strings containing these should be ordered. +This is most useful for different language definitions. +.Pp +The specification file can consist of three statements: +.Ar charmap +, +.Ar substitute +, and +.Ar order +. Of these, only the order +statement is required. When charmap or substitute is +supplied, these statements must be ordered as above. Any +statements after the order statement are ignored. +.Pp +Lines in the specification file beginning with a # are +treated as comments and are ignored. Blank lines are also +ignored. +.Pp +.Ar charmap charmapfile + +.Ar charmap +defines where a mapping of the character +and collating element symbols to the actual +character encoding can be found. +.Pp +The format of +.Ar charmapfile +is shown below. Symbol +names are separated from their values by TAB or +SPACE characters. symbol-value can be specified in +a hexadecimal (\ex??) or octal (\e???) +representation, and can be only one character in length. +.Pp +.Ar symbol-name1 symbol-value1 + +.Ar symbol-name2 symbol-value2 + +.Ar ... + +.Pp +Symbol names cannot be specified in substitute +fields. Symbol names also cannot be combined with +any other representation, such as, <c>h, c<h>, +<c>\ex68, or <c><h>. Symbol names can be used with +primary and secondary ordering as in the following +example. +.Pp +The charmap statement is optional. +.Pp +.Ar substitute char with repl +The +.Ar substitute +statement substitutes the character + +.Ar char +with the string +.Ar repl +. +.Pp +The substitute statement is optional. +.Pp +.Ar order order_list + +.Ar order_list +is a list of symbols, separated by semi colons, that defines the collating sequence. The +special symbol, +.Ar ... +, specifies, in a short-hand +form, symbols that are sequential in machine code +order. +.Pp +A symbol can be up to two characters in length and +can be represented in any one of the following +ways: +.Bl -tag -width XX +.It o The symbol itself (for example, +.Ar a +for the lower-case letter +.Ar a +). +.It o The symbol chain (for example, +.Ar abc +) +.It o In octal representation (for example, +.Ar \e141 +for the letter +.Ar a +). +.It o In hexadecimal representation (for example, +.Ar \ex61 +for the letter +.Ar a +). +.It o The symbol name as defined in the charmap file (for example, +.Ar <abc> +for +.Ar \e023 abc +record in +.Ar charmapfile +). +.It o Symbols +.Ar \ea, \eb, \ef, \en, \er, \ev +are permitted in its usual C-language meaning. +.El +.Pp +The backslash character, +.Ar \e +, is used for continuation. In this case, no characters are permitted +after the backslash character. And as a quotation mark. +.Pp +Symbols enclosed in parentheses are assigned the +same primary ordering but different secondary +ordering. Symbols enclosed in curly brackets are +assigned only the same primary ordering +and different secondary ordering. +.Sh EXIT STATUS +.Ar colldef +exits with the following values: +.Ar 0 +No errors were found and the output was successfully created. +.Ar !=0 +Errors were found. +.Sh FILES +.Ar /usr/share/locale/<language>/LC_COLLATE +standard shared location for collation orders +under the locale locale +.Sh SEE ALSO +.Xr mklocale 1 , +.Xr strcoll 3 , +.Xr strxfrm 3 diff --git a/usr.bin/colldef/data/lt_LN.ISO8859-1 b/usr.bin/colldef/data/lt_LN.ISO8859-1 new file mode 100644 index 000000000000..a32adcfb3410 --- /dev/null +++ b/usr.bin/colldef/data/lt_LN.ISO8859-1 @@ -0,0 +1,16 @@ +substitute "-" with "" +substitute "\xad" with "" +substitute "\x27" with "" +substitute "\xe6" with "ae" +substitute "\xc6" with "AE" +substitute "\xdf" with "ss" +substitute "\xff" with "ij" + +order \x01;...;\x27;\x7f;...;\x9f;\ ;\xa0;.;:;\;;\,;!;?;\xa1;\xbf;a;\ + \xe0;...;\xe5;A;\xc0;...;\xc5;b;B;c;\xe7;C;\xc7;d;D;e;\xe8;...;\xeb;\ + E;\xc8;...;\xcb;f;F;g;G;h;H;i;\xec;...;\xef;I;\xcc;...;\xcf;j;J;k;K;\ + l;L;m;M;n;\xf1;N;\xd1;o;\xf2;...;\xf6;\xf8;O;\xd2;...;\xd6;\xd8;\ + p;P;q;Q;r;R;s;S;t;T;u;\xf9;...;\xfc;U;\xd9;...;\xdc;v;V;w;W;x;X;y;\ + \xfd;Y;\xdd;z;Z;\xf0;\xd0;\xfe;\xde;0;...;9;ae;AE;ss;ij;\";...;&;\ + \(;...;+;/;\<;...;\>;@;[;...;`;\{;...;~;\xa2;...;\xac;\xae;...;\xbe;\ + \xd7;\xf7 diff --git a/usr.bin/colldef/data/lt_LN.ISO_8859-1 b/usr.bin/colldef/data/lt_LN.ISO_8859-1 new file mode 100644 index 000000000000..a32adcfb3410 --- /dev/null +++ b/usr.bin/colldef/data/lt_LN.ISO_8859-1 @@ -0,0 +1,16 @@ +substitute "-" with "" +substitute "\xad" with "" +substitute "\x27" with "" +substitute "\xe6" with "ae" +substitute "\xc6" with "AE" +substitute "\xdf" with "ss" +substitute "\xff" with "ij" + +order \x01;...;\x27;\x7f;...;\x9f;\ ;\xa0;.;:;\;;\,;!;?;\xa1;\xbf;a;\ + \xe0;...;\xe5;A;\xc0;...;\xc5;b;B;c;\xe7;C;\xc7;d;D;e;\xe8;...;\xeb;\ + E;\xc8;...;\xcb;f;F;g;G;h;H;i;\xec;...;\xef;I;\xcc;...;\xcf;j;J;k;K;\ + l;L;m;M;n;\xf1;N;\xd1;o;\xf2;...;\xf6;\xf8;O;\xd2;...;\xd6;\xd8;\ + p;P;q;Q;r;R;s;S;t;T;u;\xf9;...;\xfc;U;\xd9;...;\xdc;v;V;w;W;x;X;y;\ + \xfd;Y;\xdd;z;Z;\xf0;\xd0;\xfe;\xde;0;...;9;ae;AE;ss;ij;\";...;&;\ + \(;...;+;/;\<;...;\>;@;[;...;`;\{;...;~;\xa2;...;\xac;\xae;...;\xbe;\ + \xd7;\xf7 diff --git a/usr.bin/colldef/data/ru_SU.KOI8-R b/usr.bin/colldef/data/ru_SU.KOI8-R new file mode 100644 index 000000000000..e8957986a961 --- /dev/null +++ b/usr.bin/colldef/data/ru_SU.KOI8-R @@ -0,0 +1,6 @@ +order A;a;B;b;C;c;D;d;E;e;F;f;G;g;H;h;I;i;J;j;K;k;L;l;\ + M;m;N;n;O;o;P;p;Q;q;R;r;S;s;T;t;U;u;V;v;W;w;X;x;\ + Y;y;Z;z;\ + á;Á;â;Â;÷;×;ç;Ç;ä;Ä;å;Å;³;£;ö;Ö;ú;Ú;é;É;ê;Ê;ë;Ë;\ + ì;Ì;í;Í;î;Î;ï;Ï;ð;Ð;ò;Ò;ó;Ó;ô;Ô;õ;Õ;æ;Æ;è;È;ã;Ã;\ + þ;Þ;û;Û;ý;Ý;ÿ;ß;ù;Ù;ø;Ø;ü;Ü;à;À;ñ;Ñ diff --git a/usr.bin/colldef/parse.y b/usr.bin/colldef/parse.y new file mode 100644 index 000000000000..47f3cd5a1b41 --- /dev/null +++ b/usr.bin/colldef/parse.y @@ -0,0 +1,248 @@ +%{ +/*- + * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> + * at Electronni Visti IA, Kiev, Ukraine. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: parse.y,v 1.2 1995/01/24 11:15:47 alex Exp alex $ + */ + +#include <err.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sysexits.h> +#include "collate.h" + +extern int line_no; +extern FILE *yyin; + +u_char __collate_charmap_table[UCHAR_MAX + 1][STR_LEN]; +u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN]; +struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1]; +struct __collate_st_name_pri __collate_name_pri_table[TABLE_SIZE]; +struct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE]; +int name_index, chain_index; +int prim_pri = 1, sec_pri = 1; +#ifdef COLLATE_DEBUG +int debug; +#endif + +char *out_file = "LC_COLLATE"; +%} +%union { + u_char ch; + u_char str[STR_LEN]; +} +%token SUBSTITUTE WITH ORDER RANGE +%token <str> STRING +%token <str> NAME +%token <str> CHAIN +%token <ch> CHAR +%% +collate : statment_list +; +statment_list : statment + | statment_list '\n' statment +; +statment : + | charmap + | substitute + | order +; +charmap : CHAIN CHAR { + strcpy(__collate_charmap_table[$2], $1); +} + | CHAR CHAR { + __collate_charmap_table[$2][0] = $1; + __collate_charmap_table[$2][1] = '\0'; +} +; +substitute : SUBSTITUTE STRING WITH STRING { + strcpy(__collate_substitute_table[$2[0]], $4); +} +; +order : ORDER order_list { + FILE *fp = fopen(out_file, "w"); + + if(!fp) + err(EX_UNAVAILABLE, "con't open destination file %s", + out_file); + + fwrite(__collate_charmap_table, sizeof(__collate_charmap_table), 1, fp); + fwrite(__collate_substitute_table, sizeof(__collate_substitute_table), 1, fp); + fwrite(__collate_char_pri_table, sizeof(__collate_char_pri_table), 1, fp); + fwrite(__collate_chain_pri_table, sizeof(__collate_chain_pri_table), 1, fp); + fwrite(__collate_name_pri_table, sizeof(__collate_name_pri_table), 1, fp); +#ifdef COLLATE_DEBUG + if (debug) + __collate_print_tables(); +#endif + exit(EX_OK); +} +; +order_list : item + | order_list ';' item +; +item : CHAR { __collate_char_pri_table[$1].prim = prim_pri++; } + | CHAIN { + if (chain_index >= TABLE_SIZE - 1) + yyerror("__collate_chain_pri_table overflow"); + strcpy(__collate_chain_pri_table[chain_index].str, $1); + __collate_chain_pri_table[chain_index++].prim = prim_pri++; +} + | NAME { + if (name_index >= TABLE_SIZE - 1) + yyerror("__collate_name_pri_table overflow"); + strcpy(__collate_name_pri_table[name_index].str, $1); + __collate_name_pri_table[name_index++].prim = prim_pri++; +} + | CHAR RANGE CHAR { + u_int i; + + if ($3 <= $1) + yyerror("Illegal range %c -- %c near line %d\n", + $1, $3, line_no); + + for (i = $1; i <= $3; i++) { + __collate_char_pri_table[(u_char)i].prim = prim_pri++; + } +} + | '{' prim_order_list '}' { + prim_pri++; +} + | '(' sec_order_list ')' { + prim_pri++; + sec_pri = 1; +} +; +prim_order_list : prim_sub_item + | prim_order_list ',' prim_sub_item +; +sec_order_list : sec_sub_item + | sec_order_list ',' sec_sub_item +; +prim_sub_item : CHAR { + __collate_char_pri_table[$1].prim = prim_pri; +} + | CHAR RANGE CHAR { + u_int i; + + if ($3 <= $1) + yyerror("Illegal range %c -- %c near line %d\n", + $1, $3, line_no); + + for (i = $1; i <= $3; i++) { + __collate_char_pri_table[(u_char)i].prim = prim_pri; + } +} + | NAME { + if (name_index >= TABLE_SIZE - 1) + yyerror("__collate_name_pri_table overflow"); + strcpy(__collate_name_pri_table[name_index].str, $1); + __collate_name_pri_table[name_index++].prim = prim_pri; +} + | CHAIN { + if (chain_index >= TABLE_SIZE - 1) + yyerror("__collate_chain_pri_table overflow"); + strcpy(__collate_chain_pri_table[chain_index].str, $1); + __collate_chain_pri_table[chain_index++].prim = prim_pri; +} +; +sec_sub_item : CHAR { + __collate_char_pri_table[$1].prim = prim_pri; + __collate_char_pri_table[$1].sec = sec_pri++; +} + | CHAR RANGE CHAR { + u_int i; + + if ($3 <= $1) + yyerror("Illegal range %c -- %c near line %d\n", + $1, $3, line_no); + + for (i = $1; i <= $3; i++) { + __collate_char_pri_table[(u_char)i].prim = prim_pri; + __collate_char_pri_table[(u_char)i].sec = sec_pri++; + } +} + | NAME { + if (name_index >= TABLE_SIZE - 1) + yyerror("__collate_name_pri_table overflow"); + strcpy(__collate_name_pri_table[name_index].str, $1); + __collate_name_pri_table[name_index].prim = prim_pri; + __collate_name_pri_table[name_index++].sec = sec_pri++; +} + | CHAIN { + if (chain_index >= TABLE_SIZE - 1) + yyerror("__collate_chain_pri_table overflow"); + strcpy(__collate_chain_pri_table[chain_index].str, $1); + __collate_chain_pri_table[chain_index].prim = prim_pri; + __collate_chain_pri_table[chain_index++].sec = sec_pri++; +} +; +%% +main(ac, av) + char **av; +{ + int ch; + +#ifdef COLLATE_DEBUG + while((ch = getopt(ac, av, ":do:")) != EOF) { +#else + while((ch = getopt(ac, av, ":o:")) != EOF) { +#endif + switch (ch) + { +#ifdef COLLATE_DEBUG + case 'd': + debug++; + break; +#endif + case 'o': + out_file = optarg; + break; + + default: + fprintf(stderr, "Usage: %s [-o out_file] [in_file]\n", + av[0]); + exit(EX_OK); + } + } + ac -= optind; + av += optind; + if(ac > 0) { + if((yyin = fopen(*av, "r")) == 0) + err(EX_UNAVAILABLE, "can't open source file %s", *av); + } + for(ch = 0; ch <= UCHAR_MAX; ch++) + __collate_substitute_table[ch][0] = ch; + yyparse(); + return 0; +} + +yyerror(msg) + char *msg; +{ + errx(EX_UNAVAILABLE, "%s near line %d", msg, line_no); +} diff --git a/usr.bin/colldef/scan.l b/usr.bin/colldef/scan.l new file mode 100644 index 000000000000..3be046335080 --- /dev/null +++ b/usr.bin/colldef/scan.l @@ -0,0 +1,212 @@ +%x string name charmap +%{ +/*- + * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> + * at Electronni Visti IA, Kiev, Ukraine. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: scan.l,v 1.1 1995/01/22 20:37:31 alex Exp alex $ + */ + +#include <err.h> +#include <unistd.h> +#include <string.h> +#include <sysexits.h> +#include "collate.h" +#include "y.tab.h" + +int line_no = 1; +u_char buf[STR_LEN], *ptr; +FILE *map_fp; +YY_BUFFER_STATE main_buf, map_buf; +#ifdef FLEX_DEBUG +YYSTYPE yylval; +#endif /* FLEX_DEBUG */ +%} +%% +<INITIAL,charmap>[ \t] ; +\" { ptr = buf; BEGIN(string); } +\< { ptr = buf; BEGIN(name); } +^#.*\n line_no++; +^\n line_no++; +\\\n line_no++; +\\t { yylval.ch = '\t'; return CHAR; } +\\n { yylval.ch = '\n'; return CHAR; } +\\b { yylval.ch = '\b'; return CHAR; } +\\f { yylval.ch = '\f'; return CHAR; } +\\v { yylval.ch = '\v'; return CHAR; } +\\r { yylval.ch = '\r'; return CHAR; } +\\a { yylval.ch = '\a'; return CHAR; } +\\. { yylval.ch = yytext[1]; return CHAR; } +<INITIAL,charmap>\n { line_no++; return '\n'; } +[;,{}()] return *yytext; +substitute return SUBSTITUTE; +with return WITH; +order return ORDER; +charmap BEGIN(charmap); +;[ \t]*\.\.\.[ \t]*; return RANGE; +\\[0-7]{3} { + u_int v; + + sscanf(&yytext[1], "%o", &v); + yylval.ch = (u_char)v; + return CHAR; +} +\\x[0-9a-z]{2} { + u_int v; + + sscanf(&yytext[2], "%x", &v); + yylval.ch = (u_char)v; + return CHAR; +} +[^;,{}() \t\n"<]+ { + if(yyleng == 1) { + yylval.ch = *yytext; + return CHAR; + } + if(yyleng > STR_LEN - 1) + errx(EX_UNAVAILABLE, "chain buffer overflaw near line %u", + line_no); + strcpy(yylval.str, yytext); + return CHAIN; +} +<name>\\\> { + if(ptr >= buf + sizeof(buf) - 1) + errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u", + line_no); + *ptr++ = '>'; +} +<string>\\\" { + if(ptr >= buf + sizeof(buf) - 1) + errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u", + line_no); + *ptr++ = '"'; +} +<name>\> { + *ptr = '\0'; + strcpy(yylval.str, buf); + BEGIN(INITIAL); + return NAME; +} +<string>\" { + *ptr = '\0'; + strcpy(yylval.str, buf); + BEGIN(INITIAL); + return STRING; +} +<name,string>. { + if(ptr >= buf + sizeof(buf) - 1) + errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u", + line_no); + *ptr++ = *yytext; +} +<name,string>\\t { + if(ptr >= buf + sizeof(buf) - 1) + errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u", + line_no); + *ptr++ = '\t'; +} +<name,string>\\b { + if(ptr >= buf + sizeof(buf) - 1) + errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u", + line_no); + *ptr++ = '\b'; +} +<name,string>\\f { + if(ptr >= buf + sizeof(buf) - 1) + errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u", + line_no); + *ptr++ = '\f'; +} +<name,string>\\v { + if(ptr >= buf + sizeof(buf) - 1) + errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u", + line_no); + *ptr++ = '\v'; +} +<name,string>\\n { + if(ptr >= buf + sizeof(buf) - 1) + errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u", + line_no); + *ptr++ = '\n'; +} +<name,string>\\r { + if(ptr >= buf + sizeof(buf) - 1) + errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u", + line_no); + *ptr++ = '\r'; +} +<name,string>\\a { + if(ptr >= buf + sizeof(buf) - 1) + errx(EX_UNAVAILABLE, "name/string buffer overflaw near line %u", + line_no); + *ptr++ = '\a'; +} +<name,string><<EOF>> { + errx(EX_UNAVAILABLE, "unterminated name/string near line %u", line_no); +} +<name,string>\\x[0-9a-f]{2} { + u_int v; + + sscanf(&yytext[2], "%x", &v); + *ptr++ = (u_char)v; +} +<name,string>\\[0-7]{3} { + u_int v; + + sscanf(&yytext[1], "%o", &v); + *ptr++ = (u_char)v; +} +<charmap>[^ \t\n]+ { + if((map_fp = fopen(yytext, "r")) == 0) + err(EX_UNAVAILABLE, "can't open charmap file %s near line %u", + yytext, line_no); + map_buf = yy_new_buffer(map_fp, YY_BUF_SIZE); + main_buf = YY_CURRENT_BUFFER; + yy_switch_to_buffer(map_buf); + BEGIN(INITIAL); +} +<charmap><<EOF>> { + errx(EX_UNAVAILABLE, "charmap file name expected near line %u", + line_no); +} +<<EOF>> { + if(map_fp) { + yy_switch_to_buffer(main_buf); + yy_delete_buffer(map_buf); + fclose(map_fp); + map_fp = 0; + } + else + yyterminate(); +} +%% +#ifdef FLEX_DEBUG +main() +{ + while(yylex()) + ; + return 0; +} +#endif /* FLEX_DEBUG */ |