X-Git-Url: http://git.csclub.uwaterloo.ca/?p=kopensolaris-gnu%2Fglibc.git;a=blobdiff_plain;f=catgets%2Fgencat.c;h=d632f82bc4f70e81d84e36adebdf62ed1000fa53;hp=a1936060277cb16697f41f33ce5d08a3c383d081;hb=f1d197bcca8730b79b9802092c96e2319b13ef19;hpb=e38352a69cd05d8f1593feb1c4ff740a3cbe27cb diff --git a/catgets/gencat.c b/catgets/gencat.c index a193606027..d632f82bc4 100644 --- a/catgets/gencat.c +++ b/catgets/gencat.c @@ -1,32 +1,33 @@ -/* Copyright (C) 1996 Free Software Foundation, Inc. -This file is part of the GNU C Library. -Contributed by Ulrich Drepper, . +/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. -You should have received a copy of the GNU Library General Public -License along with the GNU C Library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include #endif +#include #include #include #include #include #include -#include +#include #include #include #include @@ -87,22 +88,56 @@ struct catalog /* If non-zero force creation of new file, not using existing one. */ static int force_new; -/* Long options. */ -static const struct option long_options[] = +/* Name of output file. */ +static const char *output_name; + +/* Name of generated C header file. */ +static const char *header_name; + +/* Name and version of program. */ +static void print_version (FILE *stream, struct argp_state *state); +void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; + +#define OPT_NEW 1 + +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = +{ + { "header", 'H', N_("NAME"), 0, + N_("Create C header file NAME containing symbol definitions") }, + { "new", OPT_NEW, NULL, 0, + N_("Do not use existing catalog, force new output file") }, + { "output", 'o', N_("NAME"), 0, N_("Write output to file NAME") }, + { NULL, 0, NULL, 0, NULL } +}; + +/* Short description of program. */ +static const char doc[] = N_("Generate message catalog.\ +\vIf INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n\ +is -, output is written to standard output.\n"); + +/* Strings for arguments in help texts. */ +static const char args_doc[] = N_("\ +-o OUTPUT-FILE [INPUT-FILE]...\n[OUTPUT-FILE [INPUT-FILE]...]"); + +/* Prototype for option handler. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +/* Function to print some extra text in the help message. */ +static char *more_help (int key, const char *text, void *input); + +/* Data structure to communicate with argp functions. */ +static struct argp argp = { - { "header", required_argument, NULL, 'H' }, - { "help", no_argument, NULL, 'h' }, - { "new", no_argument, &force_new, 1 }, - { "output", required_argument, NULL, 'o' }, - { "version", no_argument, NULL, 'V' }, - { NULL, 0, NULL, 0 } + options, parse_opt, args_doc, doc, NULL, more_help }; + /* Wrapper functions with error checking for standard functions. */ extern void *xmalloc (size_t n); +extern void *xcalloc (size_t n, size_t s); /* Prototypes for local functions. */ -static void usage (int status) __attribute__ ((noreturn)); static void error_print (void); static struct catalog *read_input_file (struct catalog *current, const char *fname); @@ -118,11 +153,7 @@ int main (int argc, char *argv[]) { struct catalog *result; - const char *output_name; - const char *header_name; - int do_help; - int do_version; - int opt; + int remaining; /* Set program name for messages. */ error_print_progname = error_print; @@ -134,55 +165,21 @@ main (int argc, char *argv[]) textdomain (PACKAGE); /* Initialize local variables. */ - do_help = 0; - do_version = 0; - output_name = NULL; - header_name = NULL; result = NULL; - while ((opt = getopt_long (argc, argv, "hH:o:V", long_options, NULL)) != EOF) - switch (opt) - { - case '\0': /* Long option. */ - break; - case 'h': - do_help = 1; - break; - case 'H': - header_name = optarg; - break; - case 'o': - output_name = optarg; - break; - case 'V': - do_version = 1; - break; - default: - usage (EXIT_FAILURE); - } - - /* Version information is requested. */ - if (do_version) - { - fprintf (stderr, "%s - GNU %s %s\n", program_invocation_name, - "libc", VERSION); - exit (EXIT_SUCCESS); - } - - /* Help is requested. */ - if (do_help) - usage (EXIT_SUCCESS); + /* Parse and process arguments. */ + argp_parse (&argp, argc, argv, 0, &remaining, NULL); /* Determine output file. */ if (output_name == NULL) - output_name = optind < argc ? argv[optind++] : "-"; + output_name = remaining < argc ? argv[remaining++] : "-"; /* Process all input files. */ setlocale (LC_CTYPE, "C"); - if (optind < argc) + if (remaining < argc) do - result = read_input_file (result, argv[optind]); - while (++optind < argc); + result = read_input_file (result, argv[remaining]); + while (++remaining < argc); else result = read_input_file (NULL, "-"); @@ -194,27 +191,54 @@ main (int argc, char *argv[]) } +/* Handle program arguments. */ +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case 'H': + header_name = arg; + break; + case OPT_NEW: + force_new = 1; + break; + case 'o': + output_name = arg; + break; + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + + +static char * +more_help (int key, const char *text, void *input) +{ + switch (key) + { + case ARGP_KEY_HELP_EXTRA: + /* We print some extra information. */ + return strdup (gettext ("\ +Report bugs using the `glibcbug' script to .\n")); + default: + break; + } + return (char *) text; +} + +/* Print the version information. */ static void -usage (int status) +print_version (FILE *stream, struct argp_state *state) { - if (status != EXIT_SUCCESS) - fprintf (stderr, gettext ("Try `%s --help' for more information.\n"), - program_invocation_name); - else - printf(gettext ("\ -Usage: %s [OPTION]... -o OUTPUT-FILE [INPUT-FILE]...\n\ - %s [OPTION]... [OUTPUT-FILE [INPUT-FILE]...]\n\ -Mandatory arguments to long options are mandatory for short options too.\n\ - -H, --header create C header file containing symbol definitions\n\ - -h, --help display this help and exit\n\ - --new do not use existing catalog, force new output file\n\ - -o, --output=NAME write output to file NAME\n\ - -V, --version output version information and exit\n\ -If INPUT-FILE is -, input is read from standard input. If OUTPUT-FILE\n\ -is -, output is written to standard output.\n"), - program_invocation_name, program_invocation_name); - - exit (status); + fprintf (stream, "gencat (GNU %s) %s\n", PACKAGE, VERSION); + fprintf (stream, gettext ("\ +Copyright (C) %s Free Software Foundation, Inc.\n\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ +"), "1996, 1997"); + fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); } @@ -252,16 +276,13 @@ read_input_file (struct catalog *current, const char *fname) /* If we haven't seen anything yet, allocate result structure. */ if (current == NULL) { - current = (struct catalog *) xmalloc (sizeof (*current)); + current = (struct catalog *) xcalloc (1, sizeof (*current)); - current->all_sets = NULL; - current->total_messages = 0; - current->last_set = 0; - current->current_set = find_set (current, NL_SETD); - -#define obstack_chunk_alloc xmalloc +#define obstack_chunk_alloc malloc #define obstack_chunk_free free obstack_init (¤t->mem_pool); + + current->current_set = find_set (current, NL_SETD); } buf = NULL; @@ -309,7 +330,7 @@ read_input_file (struct catalog *current, const char *fname) /* This is a comment line. Do nothing. */; else if (strncmp (&this_line[1], "set", 3) == 0) { - int cnt = sizeof ("cnt"); + int cnt = sizeof ("set"); int set_number; const char *symbol = NULL; while (isspace (this_line[cnt])) @@ -342,7 +363,7 @@ read_input_file (struct catalog *current, const char *fname) } else { - /* We have found seomthing which looks like a + /* We have found seomthing that looks like a correct identifier. */ struct set_list *runp; @@ -815,16 +836,18 @@ write_out (struct catalog *catalog, const char *output_name, #define out. But we have to take care for the set not having a symbolic name. */ if (message_run->symbol != NULL) - if (set_run->symbol == NULL) - fprintf (fp, "#define AutomaticSet%d%s %#x\t/* %s:%Zu */\n", - set_run->number, message_run->symbol, - message_run->number, message_run->fname, - message_run->line); - else - fprintf (fp, "#define %s%s %#x\t/* %s:%Zu */\n", - set_run->symbol, message_run->symbol, - message_run->number, message_run->fname, - message_run->line); + { + if (set_run->symbol == NULL) + fprintf (fp, "#define AutomaticSet%d%s %#x\t/* %s:%Zu */\n", + set_run->number, message_run->symbol, + message_run->number, message_run->fname, + message_run->line); + else + fprintf (fp, "#define %s%s %#x\t/* %s:%Zu */\n", + set_run->symbol, message_run->symbol, + message_run->number, message_run->fname, + message_run->line); + } message_run = message_run->next; } @@ -854,10 +877,8 @@ find_set (struct catalog *current, int number) result = result->next; /* Prepare new message set. */ - result = (struct set_list *) xmalloc (sizeof (*result)); + result = (struct set_list *) xcalloc (1, sizeof (*result)); result->number = number; - result->deleted = 0; - result->messages = NULL; result->next = current->all_sets; current->all_sets = result; @@ -965,16 +986,20 @@ read_old (struct catalog *catalog, const char *file_name) old_cat_obj.status = closed; old_cat_obj.cat_name = file_name; + old_cat_obj.nlspath = NULL; + __libc_lock_init (old_cat_obj.lock); /* Try to open catalog, but don't look through the NLSPATH. */ - __open_catalog (&old_cat_obj, 0); + __open_catalog (&old_cat_obj); - if (old_cat_obj.status != mmaped && old_cat_obj.status != malloced) - if (errno == ENOENT) - /* No problem, the catalog simply does not exist. */ - return; - else - error (EXIT_FAILURE, errno, gettext ("while opening old catalog file")); + if (old_cat_obj.status != mmapped && old_cat_obj.status != malloced) + { + if (errno == ENOENT) + /* No problem, the catalog simply does not exist. */ + return; + else + error (EXIT_FAILURE, errno, gettext ("while opening old catalog file")); + } /* OK, we have the catalog loaded. Now read all messages and merge them. When set and message number clash for any message the new