diff options
Diffstat (limited to 'usr.bin/mkesdb')
-rw-r--r-- | usr.bin/mkesdb/Makefile | 9 | ||||
-rw-r--r-- | usr.bin/mkesdb/Makefile.inc | 6 | ||||
-rw-r--r-- | usr.bin/mkesdb/ldef.h | 40 | ||||
-rw-r--r-- | usr.bin/mkesdb/lex.l | 99 | ||||
-rw-r--r-- | usr.bin/mkesdb/mkesdb.1 | 84 | ||||
-rw-r--r-- | usr.bin/mkesdb/yacc.y | 332 |
6 files changed, 570 insertions, 0 deletions
diff --git a/usr.bin/mkesdb/Makefile b/usr.bin/mkesdb/Makefile new file mode 100644 index 0000000..d4bd03f --- /dev/null +++ b/usr.bin/mkesdb/Makefile @@ -0,0 +1,9 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../lib/libc/iconv + +PROG= mkesdb +LDFLAGS+= -L${.OBJDIR}/../../lib/libc + +.include "${.CURDIR}/Makefile.inc" +.include <bsd.prog.mk> diff --git a/usr.bin/mkesdb/Makefile.inc b/usr.bin/mkesdb/Makefile.inc new file mode 100644 index 0000000..33d0b36 --- /dev/null +++ b/usr.bin/mkesdb/Makefile.inc @@ -0,0 +1,6 @@ +# $FreeBSD$ + +SRCS+= lex.l yacc.y +CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../mkesdb \ + -I${.CURDIR}/../../lib/libc/iconv \ + --param max-inline-insns-single=64 diff --git a/usr.bin/mkesdb/ldef.h b/usr.bin/mkesdb/ldef.h new file mode 100644 index 0000000..a14277c --- /dev/null +++ b/usr.bin/mkesdb/ldef.h @@ -0,0 +1,40 @@ +/* $FreeBSD$ */ +/* $NetBSD: ldef.h,v 1.2 2005/06/27 01:23:59 fvdl Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +extern int line_number; +extern int yyerror(const char *); +extern int yylex(void); +extern int yyparse(void); + +struct named_csid { + STAILQ_ENTRY(named_csid) ci_entry; + char *ci_symbol; + u_int32_t ci_csid; +}; +STAILQ_HEAD(named_csid_list, named_csid); diff --git a/usr.bin/mkesdb/lex.l b/usr.bin/mkesdb/lex.l new file mode 100644 index 0000000..033897a --- /dev/null +++ b/usr.bin/mkesdb/lex.l @@ -0,0 +1,99 @@ +/* $FreeBSD$ */ +/* $NetBSD: lex.l,v 1.3 2006/02/09 22:03:15 dogcow Exp $ */ + +%{ +/*- + * Copyright (c)2003 Citrus Project, + * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +#include <sys/cdefs.h> +#include <sys/endian.h> +#include <sys/queue.h> +#include <sys/types.h> + +#include <assert.h> +#include <errno.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "ldef.h" +#include "yacc.h" + +int line_number = 1; +%} +%option nounput + +%x COMMENT + +%% + +[ \t]+ { } +#.*[\n]|"//".*[\n]|[\n] { line_number++; return (R_LN); } + +"/*" { BEGIN COMMENT; } +<COMMENT>"*/" { BEGIN 0; } +<COMMENT>[\n] { line_number++; } +<COMMENT>. { } +<COMMENT><<EOF>> { + yyerror("unexpected file end (unterminate comment)\n"); + exit(1); + } + +([1-9][0-9]*)|(0[0-9]*)|(0[xX][0-9A-Fa-f]+) { + yylval.i_value = strtoul(yytext, NULL, 0); + return (L_IMM); + } + +"NAME" { return (R_NAME); } +"ENCODING" { return (R_ENCODING); } +"VARIABLE" { return (R_VARIABLE); } +"DEFCSID" { return (R_DEFCSID); } +"INVALID" { return (R_INVALID); } + +\"([^\"\n]*(\\\")?)*\"|\'([^\'\n]*(\\\')?)*\' { + size_t len; + + len = strlen(yytext); + yylval.s_value = malloc(len - 1); + strlcpy(yylval.s_value, yytext + 1, len - 1); + return (L_STRING); + } +[^ =/\-0-9\t\n][^ \t\n]* { + yylval.s_value = strdup(yytext); + return (L_STRING); + } + +%% + +#ifndef yywrap +int +yywrap(void) +{ + + return (1); +} +#endif diff --git a/usr.bin/mkesdb/mkesdb.1 b/usr.bin/mkesdb/mkesdb.1 new file mode 100644 index 0000000..2e06371 --- /dev/null +++ b/usr.bin/mkesdb/mkesdb.1 @@ -0,0 +1,84 @@ +.\" Copyright (c) 2009 Gabor Kovesdan <gabor@FreeBSD.org> +.\" 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- +.\" Portable Operating System Interface (POSIX), The Open Group Base +.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of +.\" Electrical and Electronics Engineers, Inc and The Open Group. In the +.\" event of any discrepancy between this version and the original IEEE and +.\" The Open Group Standard, the original IEEE and The Open Group Standard is +.\" the referee document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" $FreeBSD$ +.\" +.Dd November 1, 2009 +.Dt mkesdb 1 +.Os +.Sh NAME +.Nm mkesdb +.Nd generates conversion catalog for +.Xr iconv 3 +.Sh SYNOPSIS +.Nm +.Op Fl md +.Fl o +.Ar outfile +.Ar infile +.Sh DESCRIPTION +The +.Nm +utility generates conversion catalog for the +.Xr iconv 3 +library. +The generated data includes a list of supported encodings +and their most important characteristics, like the pluggable +module to use +.Pp +The following options are available: +.Bl -tag -width 0123 +.It Fl d +Turns on debug mode. +.It Fl m +Process directory catalog or alias file. +If not specified, the input file is treated as an encoding description. +.It Fl o Ar outfile +Put generated binary data to +.Ar outfile . +.El +.Sh EXIT STATUS +.Ex -std mkesdb +.Sh SEE ALSO +.Xr iconv 1 , +.Xr iconv 3 , +.Xr mkcsmapper 1 +.Sh HISTORY +.Nm +first appeared in +.Nx 2.0 , and made its appearance in +.Fx 9.0 . +.Sh AUTHORS +This manual page was written by +.An Gabor Kovesdan Aq gabor@FreeBSD.org . diff --git a/usr.bin/mkesdb/yacc.y b/usr.bin/mkesdb/yacc.y new file mode 100644 index 0000000..0c01b61 --- /dev/null +++ b/usr.bin/mkesdb/yacc.y @@ -0,0 +1,332 @@ +/* $FreeBSD$ */ +/* $NetBSD: yacc.y,v 1.4 2005/06/02 02:09:25 lukem Exp $ */ + +%{ +/*- + * Copyright (c)2003 Citrus Project, + * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ + +#include <sys/cdefs.h> +#include <sys/types.h> +#include <sys/queue.h> + +#include <assert.h> +#include <err.h> +#include <errno.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "citrus_namespace.h" +#include "citrus_types.h" +#include "citrus_region.h" +#include "citrus_esdb_file.h" +#include "citrus_db_hash.h" +#include "citrus_db_factory.h" +#include "citrus_lookup_factory.h" + +#include "ldef.h" + +extern FILE *yyin; + +static struct named_csid_list named_csids; +static char *encoding, *name, *output = NULL, *variable; +static u_int32_t invalid; +static int debug = 0, num_csids = 0, use_invalid = 0; + +static void dump_file(void); +static void register_named_csid(char *, u_int32_t); +static void set_invalid(u_int32_t); +static void set_prop_string(const char *, char **, char **); +%} +%union { + u_int32_t i_value; + char *s_value; +} + +%token R_NAME R_ENCODING R_VARIABLE R_DEFCSID R_INVALID +%token R_LN +%token <i_value> L_IMM +%token <s_value> L_STRING + +%% + +file : property + { dump_file(); } + +property : /* empty */ + | property R_LN + | property name R_LN + | property encoding R_LN + | property variable R_LN + | property defcsid R_LN + | property invalid R_LN + +name : R_NAME L_STRING + { + set_prop_string("NAME", &name, &$2); + } + +encoding : R_ENCODING L_STRING + { + set_prop_string("ENCODING", &encoding, &$2); + } +variable : R_VARIABLE L_STRING + { + set_prop_string("VARIABLE", &variable, &$2); + } +defcsid : R_DEFCSID L_STRING L_IMM + { + register_named_csid($2, $3); + $2 = NULL; + } +invalid : R_INVALID L_IMM + { + set_invalid($2); + } +%% + +int +yyerror(const char *s) +{ + + fprintf(stderr, "%s in %d\n", s, line_number); + + return (0); +} + +#define CHKERR(ret, func, a) \ +do { \ + ret = func a; \ + if (ret) \ + errx(EXIT_FAILURE, "%s: %s", #func, strerror(ret)); \ +} while (/*CONSTCOND*/0) +static void +dump_file(void) +{ + struct _db_factory *df; + struct _region data; + struct named_csid *csid; + FILE *fp; + char buf[100]; + void *serialized; + size_t size; + int i, ret; + + ret = 0; + if (!name) { + fprintf(stderr, "NAME is mandatory.\n"); + ret = 1; + } + if (!encoding) { + fprintf(stderr, "ENCODING is mandatory.\n"); + ret = 1; + } + if (ret) + exit(1); + + /* + * build database + */ + CHKERR(ret, _db_factory_create, (&df, _db_hash_std, NULL)); + + /* store version */ + CHKERR(ret, _db_factory_add32_by_s, (df, _CITRUS_ESDB_SYM_VERSION, + _CITRUS_ESDB_VERSION)); + + /* store encoding */ + CHKERR(ret, _db_factory_addstr_by_s, (df, _CITRUS_ESDB_SYM_ENCODING, + encoding)); + + /* store variable */ + if (variable) + CHKERR(ret, _db_factory_addstr_by_s, + (df, _CITRUS_ESDB_SYM_VARIABLE, variable)); + + /* store invalid */ + if (use_invalid) + CHKERR(ret, _db_factory_add32_by_s, (df, + _CITRUS_ESDB_SYM_INVALID, invalid)); + + /* store num of charsets */ + CHKERR(ret, _db_factory_add32_by_s, (df, _CITRUS_ESDB_SYM_NUM_CHARSETS, + num_csids)); + i = 0; + STAILQ_FOREACH(csid, &named_csids, ci_entry) { + snprintf(buf, sizeof(buf), _CITRUS_ESDB_SYM_CSNAME_PREFIX "%d", + i); + CHKERR(ret, _db_factory_addstr_by_s, + (df, buf, csid->ci_symbol)); + snprintf(buf, sizeof(buf), _CITRUS_ESDB_SYM_CSID_PREFIX "%d", + i); + CHKERR(ret, _db_factory_add32_by_s, (df, buf, csid->ci_csid)); + i++; + } + + /* + * dump database to file + */ + fp = output ? fopen(output, "wb") : stdout; + if (fp == NULL) { + perror("fopen"); + exit(1); + } + + /* dump database body */ + size = _db_factory_calc_size(df); + serialized = malloc(size); + _region_init(&data, serialized, size); + CHKERR(ret, _db_factory_serialize, (df, _CITRUS_ESDB_MAGIC, &data)); + if (fwrite(serialized, size, 1, fp) != 1) + err(EXIT_FAILURE, "fwrite"); + + fclose(fp); +} + +static void +set_prop_string(const char *res, char **store, char **data) +{ + char buf[256]; + + if (*store) { + snprintf(buf, sizeof(buf), + "%s is duplicated. ignored the one", res); + yyerror(buf); + return; + } + + *store = *data; + *data = NULL; +} + +static void +set_invalid(u_int32_t inv) +{ + + invalid = inv; + use_invalid = 1; +} + +static void +register_named_csid(char *sym, u_int32_t val) +{ + struct named_csid *csid; + + STAILQ_FOREACH(csid, &named_csids, ci_entry) { + if (strcmp(csid->ci_symbol, sym) == 0) { + yyerror("multiply defined CSID"); + exit(1); + } + } + + csid = malloc(sizeof(*csid)); + if (csid == NULL) { + perror("malloc"); + exit(1); + } + csid->ci_symbol = sym; + csid->ci_csid = val; + STAILQ_INSERT_TAIL(&named_csids, csid, ci_entry); + num_csids++; +} + +static void +do_mkdb(FILE *in) +{ + FILE *out; + int ret; + + /* dump DB to file */ + out = output ? fopen(output, "wb") : stdout; + if (out == NULL) + err(EXIT_FAILURE, "fopen"); + + ret = _lookup_factory_convert(out, in); + fclose(out); + if (ret && output) + unlink(output); /* dump failure */ + if (ret) + errx(EXIT_FAILURE, "%s\n", strerror(ret)); +} + +static void +usage(void) +{ + errx(EXIT_FAILURE, + "usage:\n" + "\t%s [-o outfile] [infile]\n" + "\t%s -m [-o outfile] [infile]", + getprogname(), getprogname()); +} + +int +main(int argc, char **argv) +{ + FILE *in = NULL; + int ch, mkdb = 0; + + while ((ch = getopt(argc, argv, "do:m")) != EOF) { + switch (ch) { + case 'd': + debug = 1; + break; + case 'o': + output = strdup(optarg); + break; + case 'm': + mkdb = 1; + break; + default: + usage(); + } + } + + argc -= optind; + argv += optind; + switch (argc) { + case 0: + in = stdin; + break; + case 1: + in = fopen(argv[0], "r"); + if (!in) + err(EXIT_FAILURE, "%s", argv[0]); + break; + default: + usage(); + } + + if (mkdb) + do_mkdb(in); + else { + STAILQ_INIT(&named_csids); + yyin = in; + yyparse(); + } + + return (0); +} |