-/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996.
# include <config.h>
#endif
+#include <argp.h>
#include <ctype.h>
#include <endian.h>
#include <errno.h>
#include <error.h>
#include <fcntl.h>
-#include <getopt.h>
#include <locale.h>
#include <libintl.h>
#include <limits.h>
/* 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);
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;
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)
- {
- printf ("gencat (GNU %s) %s\n", PACKAGE, VERSION);
- printf (_("\
-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");
- printf (_("Written by %s.\n"), "Ulrich Drepper");
-
- 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, "-");
}
-static void
-usage (int status)
+/* Handle program arguments. */
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
{
- if (status != EXIT_SUCCESS)
- fprintf (stderr, gettext ("Try `%s --help' for more information.\n"),
- program_invocation_name);
- else
+ switch (key)
{
- 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);
- fputs (gettext ("\
-Report bugs using the `glibcbug' script to <bugs@gnu.ai.mit.edu>.\n"),
- stdout);
+ 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;
+}
+
- exit (status);
+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 <bugs@gnu.org>.\n"));
+ default:
+ break;
+ }
+ return (char *) text;
+}
+
+/* Print the version information. */
+static void
+print_version (FILE *stream, struct argp_state *state)
+{
+ 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");
}
/* If we haven't seen anything yet, allocate result structure. */
if (current == NULL)
{
- current = (struct catalog *) xmalloc (sizeof (*current));
-
- current->all_sets = NULL;
- current->total_messages = 0;
- current->last_set = 0;
- current->current_set = find_set (current, NL_SETD);
+ current = (struct catalog *) xcalloc (1, sizeof (*current));
#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;
/* 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]))
#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;
}
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;
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 != 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"));
+ {
+ 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