summaryrefslogtreecommitdiff
path: root/Build/source/utils/texinfo/info/infokey.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/texinfo/info/infokey.c')
-rw-r--r--Build/source/utils/texinfo/info/infokey.c924
1 files changed, 0 insertions, 924 deletions
diff --git a/Build/source/utils/texinfo/info/infokey.c b/Build/source/utils/texinfo/info/infokey.c
deleted file mode 100644
index 4f49e74f78c..00000000000
--- a/Build/source/utils/texinfo/info/infokey.c
+++ /dev/null
@@ -1,924 +0,0 @@
-/* infokey.c -- compile ~/.infokey to ~/.info.
- $Id: infokey.c,v 1.17 2008/02/26 16:51:05 karl Exp $
-
- Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005, 2007, 2008
- Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- Written by Andrew Bettison <andrewb@zip.com.au>. */
-
-#include "info.h"
-#include "infomap.h"
-#include "infokey.h"
-#include "key.h"
-#include "getopt.h"
-
-char *program_name = "infokey";
-
-/* Non-zero means print version info only. */
-static int print_version_p = 0;
-
-/* Non-zero means print a short description of the options. */
-static int print_help_p = 0;
-
-/* String specifying the source file. This is set by the user on the
- command line, or a default is used. */
-static char *input_filename = (char *) NULL;
-
-/* String specifying the name of the file to output to. This is
- set by the user on the command line, or a default is used. */
-static char *output_filename = (char *) NULL;
-
-/* Structure describing the options that Infokey accepts. We pass this
- structure to getopt_long (). If you add or otherwise change this
- structure, you must also change the string which follows it. */
-static struct option long_options[] =
-{
- {"output", 1, 0, 'o'},
- {"help", 0, &print_help_p, 1},
- {"version", 0, &print_version_p, 1},
- {NULL, 0, NULL, 0}
-};
-
-/* String describing the shorthand versions of the long options found above. */
-static char *short_options = "o:";
-
-/* Structure for holding the compiled sections. */
-enum sect_e
- {
- info = 0,
- ea = 1,
- var = 2
- };
-struct sect
- {
- unsigned int cur;
- unsigned char data[INFOKEY_MAX_SECTIONLEN];
- };
-
-/* Some "forward" declarations. */
-static char *mkpath (const char *dir, const char *file);
-static int compile (FILE *fp, const char *filename, struct sect *sections);
-static int write_infokey_file (FILE *fp, struct sect *sections);
-static void syntax_error (const char *filename,
- unsigned int linenum, const char *fmt,
- const void *a1, const void *a2, const void *a3, const void *a4);
-static void error_message (int error_code, const char *fmt,
- const void *a1, const void *a2, const void *a3, const void *a4);
-static void suggest_help (void);
-static void short_help (void);
-
-
-/* **************************************************************** */
-/* */
-/* Main Entry Point to the Infokey Program */
-/* */
-/* **************************************************************** */
-
-int
-main (int argc, char **argv)
-{
- int getopt_long_index; /* Index returned by getopt_long (). */
-
-#ifdef HAVE_SETLOCALE
- /* Set locale via LC_ALL. */
- setlocale (LC_ALL, "");
-#endif
-
-#ifdef ENABLE_NLS
- /* Set the text message domain. */
- bindtextdomain (PACKAGE, LOCALEDIR);
- textdomain (PACKAGE);
-#endif
-
- while (1)
- {
- int option_character;
-
- option_character = getopt_long
- (argc, argv, short_options, long_options, &getopt_long_index);
-
- /* getopt_long () returns EOF when there are no more long options. */
- if (option_character == EOF)
- break;
-
- /* If this is a long option, then get the short version of it. */
- if (option_character == 0 && long_options[getopt_long_index].flag == 0)
- option_character = long_options[getopt_long_index].val;
-
- /* Case on the option that we have received. */
- switch (option_character)
- {
- case 0:
- break;
-
- /* User is specifying the name of a file to output to. */
- case 'o':
- if (output_filename)
- free (output_filename);
- output_filename = xstrdup (optarg);
- break;
-
- default:
- suggest_help ();
- xexit (1);
- }
- }
-
- /* If the user specified --version, then show the version and exit. */
- if (print_version_p)
- {
- printf ("%s (GNU %s) %s\n", program_name, PACKAGE, VERSION);
- puts ("");
- printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
-License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n\
-This is free software: you are free to change and redistribute it.\n\
-There is NO WARRANTY, to the extent permitted by law.\n"),
- "2008");
- xexit (0);
- }
-
- /* If the `--help' option was present, show the help and exit. */
- if (print_help_p)
- {
- short_help ();
- xexit (0);
- }
-
- /* If there is one argument remaining, it is the name of the input
- file. */
- if (optind == argc - 1)
- {
- if (input_filename)
- free (input_filename);
- input_filename = xstrdup (argv[optind]);
- }
- else if (optind != argc)
- {
- error_message (0, _("incorrect number of arguments"),
- NULL, NULL, NULL, NULL);
- suggest_help ();
- xexit (1);
- }
-
- /* Use default filenames where none given. */
- {
- char *homedir;
-
- homedir = getenv ("HOME");
-#ifdef __MSDOS__
- if (!homedir)
- homedir = ".";
-#endif
- if (!input_filename)
- input_filename = mkpath (homedir, INFOKEY_SRCFILE);
- if (!output_filename)
- output_filename = mkpath (homedir, INFOKEY_FILE);
- }
-
- {
- FILE *inf;
- FILE *outf;
- int write_error;
- static struct sect sections[3];
-
- /* Open the input file. */
- inf = fopen (input_filename, "r");
- if (!inf)
- {
- error_message (errno, _("cannot open input file `%s'"),
- input_filename, NULL, NULL, NULL);
- xexit (1);
- }
-
- /* Compile the input file to its verious sections, then write the
- section data to the output file. */
-
- if (compile (inf, input_filename, sections))
- {
- /* Open the output file. */
- outf = fopen (output_filename, FOPEN_WBIN);
- if (!outf)
- {
- error_message (errno, _("cannot create output file `%s'"),
- output_filename, NULL, NULL, NULL);
- xexit (1);
- }
-
- /* Write the contents of the output file and close it. If there is
- an error writing to the file, delete it and exit with a failure
- status. */
- write_error = 0;
- if (!write_infokey_file (outf, sections))
- {
- error_message (errno, _("error writing to `%s'"),
- output_filename, NULL, NULL, NULL);
- write_error = 1;
- }
- if (fclose (outf) == EOF)
- {
- error_message (errno, _("error closing output file `%s'"),
- output_filename, NULL, NULL, NULL);
- write_error = 1;
- }
- if (write_error)
- {
- unlink (output_filename);
- xexit (1);
- }
- }
-
- /* Close the input file. */
- fclose (inf);
- }
-
- return 0;
-}
-
-static char *
-mkpath (const char *dir, const char *file)
-{
- char *p;
-
- p = xmalloc (strlen (dir) + 1 + strlen (file) + 2);
- strcpy (p, dir);
- strcat (p, "/");
- strcat (p, file);
- return p;
-}
-
-
-/* Compilation - the real work.
-
- Source file syntax
- ------------------
- The source file is a line-based text file with the following
- structure:
-
- # comments
- # more comments
-
- #info
- u prev-line
- d next-line
- ^a invalid # just beep
- \ku prev-line
- #stop
- \kd next-line
- q quit # of course!
-
- #echo-area
- ^a echo-area-beg-of-line
- ^e echo-area-end-of-line
- \kr echo-area-forward
- \kl echo-area-backward
- \kh echo-area-beg-of-line
- \ke echo-area-end-of-line
-
- #var
- scroll-step=1
- ISO-Latin=Off
-
- Lines starting with '#' are comments, and are ignored. Blank
- lines are ignored. Each section is introduced by one of the
- following lines:
-
- #info
- #echo-area
- #var
-
- The sections may occur in any order. Each section may be
- omitted completely. If the 'info' section is the first in the
- file, its '#info' line may be omitted.
-
- The 'info' and 'echo-area' sections
- -----------------------------------
- Each line in the 'info' or 'echo-area' sections has the
- following syntax:
-
- key-sequence SPACE action-name [ SPACE [ # comment ] ] \n
-
- Where SPACE is one or more white space characters excluding
- newline, "action-name" is the name of a GNU Info command,
- "comment" is any sequence of characters excluding newline, and
- "key-sequence" is a concatenation of one or more key definitions
- using the following syntax:
-
- 1. A carat ^ followed by one character indicates a single
- control character;
-
- 2. A backslash \ followed by one, two, or three octal
- digits indicates a single character having that ASCII
- code;
-
- 3. \n indicates a single NEWLINE;
- \e indicates a single ESC;
- \r indicates a single CR;
- \t indicates a single TAB;
- \b indicates a single BACKSPACE;
-
- 4. \ku indicates the Up Arrow key;
- \kd indicates the Down Arrow key;
- \kl indicates the Left Arrow key;
- \kr indicates the Right Arrow key;
- \kP indicates the Page Up (PRIOR) key;
- \kN indicates the Page Down (NEXT) key;
- \kh indicates the Home key;
- \ke indicates the End key;
- \kx indicates the DEL key;
- \k followed by any other character indicates a single
- control-K, and the following character is interpreted
- as in rules 1, 2, 3, 5 and 6.
-
- 5. \m followed by any sequence defined in rules 1, 2, 3, 4
- or 6 indicates the "Meta" modification of that key.
-
- 6. A backslash \ followed by any character not described
- above indicates that character itself. In particular:
- \\ indicates a single backslash \,
- \ (backslash-space) indicates a single space,
- \^ indicates a single caret ^,
-
- If the following line:
-
- #stop
-
- occurs anywhere in an 'info' or 'echo-area' section, that
- indicates to GNU Info to suppress all of its default key
- bindings in that context.
-
- The 'var' section
- -----------------
- Each line in the 'var' section has the following syntax:
-
- variable-name = value \n
-
- Where "variable-name" is the name of a GNU Info variable and
- "value" is the value that GNU Info will assign to that variable
- when commencing execution. There must be no white space in the
- variable name, nor between the variable name and the '='. All
- characters immediately following the '=', up to but not
- including the terminating newline, are considered to be the
- value that will be assigned. In other words, white space
- following the '=' is not ignored.
- */
-
-static int add_to_section (struct sect *s, const char *str, unsigned int len);
-static int lookup_action (const char *actname);
-
-/* Compile the input file into its various sections. Return true if no
- error was encountered.
- */
-static int
-compile (FILE *fp, const char *filename, struct sect *sections)
-{
- int error = 0;
- char rescan = 0;
- unsigned int lnum = 0;
- int c = 0;
-
- /* This parser is a true state machine, with no sneaky fetching
- of input characters inside the main loop. In other words, all
- state is fully represented by the following variables:
- */
- enum
- {
- start_of_line,
- start_of_comment,
- in_line_comment,
- in_trailing_comment,
- get_keyseq,
- got_keyseq,
- get_action,
- got_action,
- get_varname,
- got_varname,
- get_equals,
- got_equals,
- get_value
- }
- state = start_of_line;
- enum sect_e section = info;
- enum
- {
- normal,
- slosh,
- control,
- octal,
- special_key
- }
- seqstate; /* used if state == get_keyseq */
- char meta = 0;
- char ocnt = 0; /* used if state == get_keyseq && seqstate == octal */
-
- /* Data is accumulated in the following variables. The code
- avoids overflowing these strings, and throws an error
- where appropriate if a string limit is exceeded. These string
- lengths are arbitrary (and should be large enough) and their
- lengths are not hard-coded anywhere else, so increasing them
- here will not break anything. */
- char oval = 0;
- char comment[10];
- unsigned int clen = 0;
- char seq[20];
- unsigned int slen = 0;
- char act[80];
- unsigned int alen = 0;
- char varn[80];
- unsigned int varlen = 0;
- char val[80];
- unsigned int vallen = 0;
-
-#define To_seq(c) \
- do { \
- if (slen < sizeof seq) \
- seq[slen++] = meta ? Meta(c) : (c); \
- else \
- { \
- syntax_error(filename, lnum, _("key sequence too long"), \
- NULL, NULL, NULL, NULL); \
- error = 1; \
- } \
- meta = 0; \
- } while (0)
-
- sections[info].cur = 1;
- sections[info].data[0] = 0;
- sections[ea].cur = 1;
- sections[ea].data[0] = 0;
- sections[var].cur = 0;
-
- while (!error && (rescan || (c = fgetc (fp)) != EOF))
- {
- rescan = 0;
- switch (state)
- {
- case start_of_line:
- lnum++;
- if (c == '#')
- state = start_of_comment;
- else if (c != '\n')
- {
- switch (section)
- {
- case info:
- case ea:
- state = get_keyseq;
- seqstate = normal;
- slen = 0;
- break;
- case var:
- state = get_varname;
- varlen = 0;
- break;
- }
- rescan = 1;
- }
- break;
-
- case start_of_comment:
- clen = 0;
- state = in_line_comment;
- /* fall through */
- case in_line_comment:
- if (c == '\n')
- {
- state = start_of_line;
- comment[clen] = '\0';
- if (strcmp (comment, "info") == 0)
- section = info;
- else if (strcmp (comment, "echo-area") == 0)
- section = ea;
- else if (strcmp (comment, "var") == 0)
- section = var;
- else if (strcmp (comment, "stop") == 0
- && (section == info || section == ea))
- sections[section].data[0] = 1;
- }
- else if (clen < sizeof comment - 1)
- comment[clen++] = c;
- break;
-
- case in_trailing_comment:
- if (c == '\n')
- state = start_of_line;
- break;
-
- case get_keyseq:
- switch (seqstate)
- {
- case normal:
- if (c == '\n' || isspace (c))
- {
- state = got_keyseq;
- rescan = 1;
- if (slen == 0)
- {
- syntax_error (filename, lnum, _("missing key sequence"),
- NULL, NULL, NULL, NULL);
- error = 1;
- }
- }
- else if (c == '\\')
- seqstate = slosh;
- else if (c == '^')
- seqstate = control;
- else
- To_seq (c);
- break;
-
- case slosh:
- switch (c)
- {
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- seqstate = octal;
- oval = c - '0';
- ocnt = 1;
- break;
- case 'b':
- To_seq ('\b');
- seqstate = normal;
- break;
- case 'e':
- To_seq ('\033');
- seqstate = normal;
- break;
- case 'n':
- To_seq ('\n');
- seqstate = normal;
- break;
- case 'r':
- To_seq ('\r');
- seqstate = normal;
- break;
- case 't':
- To_seq ('\t');
- seqstate = normal;
- break;
- case 'm':
- meta = 1;
- seqstate = normal;
- break;
- case 'k':
- seqstate = special_key;
- break;
- default:
- /* Backslash followed by any other char
- just means that char. */
- To_seq (c);
- seqstate = normal;
- break;
- }
- break;
-
- case octal:
- switch (c)
- {
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- if (++ocnt <= 3)
- oval = oval * 8 + c - '0';
- if (ocnt == 3)
- seqstate = normal;
- break;
- default:
- ocnt = 4;
- seqstate = normal;
- rescan = 1;
- break;
- }
- if (seqstate != octal)
- {
- if (oval)
- To_seq (oval);
- else
- {
- syntax_error (filename, lnum,
- _("NUL character (\\000) not permitted"),
- NULL, NULL, NULL, NULL);
- error = 1;
- }
- }
- break;
-
- case special_key:
- To_seq (SK_ESCAPE);
- switch (c)
- {
- case 'u': To_seq (SK_UP_ARROW); break;
- case 'd': To_seq (SK_DOWN_ARROW); break;
- case 'r': To_seq (SK_RIGHT_ARROW); break;
- case 'l': To_seq (SK_LEFT_ARROW); break;
- case 'U': To_seq (SK_PAGE_UP); break;
- case 'D': To_seq (SK_PAGE_DOWN); break;
- case 'h': To_seq (SK_HOME); break;
- case 'e': To_seq (SK_END); break;
- case 'x': To_seq (SK_DELETE); break;
- default: To_seq (SK_LITERAL); rescan = 1; break;
- }
- seqstate = normal;
- break;
-
- case control:
- if (CONTROL (c))
- To_seq (CONTROL (c));
- else
- {
- syntax_error (filename, lnum,
- _("NUL character (^%c) not permitted"),
- (void *) (long) c, NULL, NULL, NULL);
- error = 1;
- }
- seqstate = normal;
- break;
- }
- break;
-
- case got_keyseq:
- if (isspace (c) && c != '\n')
- break;
- state = get_action;
- alen = 0;
- /* fall through */
- case get_action:
- if (c == '\n' || isspace (c))
- {
- int a;
-
- state = got_action;
- rescan = 1;
- if (alen == 0)
- {
- syntax_error (filename, lnum, _("missing action name"),
- (void *) (long) c, NULL, NULL, NULL);
- error = 1;
- }
- else
- {
- act[alen] = '\0';
- a = lookup_action (act);
- if (a != -1)
- {
- char av = a;
-
- if (!(add_to_section (&sections[section], seq, slen)
- && add_to_section (&sections[section], "", 1)
- && add_to_section (&sections[section], &av, 1)))
- {
- syntax_error (filename, lnum, _("section too long"),
- NULL, NULL, NULL, NULL);
- error = 1;
- }
- }
- else
- {
- syntax_error (filename, lnum, _("unknown action `%s'"),
- act, NULL, NULL, NULL);
- error = 1;
- }
- }
- }
- else if (alen < sizeof act - 1)
- act[alen++] = c;
- else
- {
- syntax_error (filename, lnum, _("action name too long"),
- NULL, NULL, NULL, NULL);
- error = 1;
- }
- break;
-
- case got_action:
- if (c == '#')
- state = in_trailing_comment;
- else if (c == '\n')
- state = start_of_line;
- else if (!isspace (c))
- {
- syntax_error (filename, lnum,
- _("extra characters following action `%s'"),
- act, NULL, NULL, NULL);
- error = 1;
- }
- break;
-
- case get_varname:
- if (c == '=')
- {
- if (varlen == 0)
- {
- syntax_error (filename, lnum, _("missing variable name"),
- NULL, NULL, NULL, NULL);
- error = 1;
- }
- state = get_value;
- vallen = 0;
- }
- else if (c == '\n' || isspace (c))
- {
- syntax_error (filename, lnum,
- _("missing `=' immediately after variable name"),
- NULL, NULL, NULL, NULL);
- error = 1;
- }
- else if (varlen < sizeof varn)
- varn[varlen++] = c;
- else
- {
- syntax_error (filename, lnum, _("variable name too long"),
- NULL, NULL, NULL, NULL);
- error = 1;
- }
- break;
-
- case get_value:
- if (c == '\n')
- {
- state = start_of_line;
- if (!(add_to_section (&sections[section], varn, varlen)
- && add_to_section (&sections[section], "", 1)
- && add_to_section (&sections[section], val, vallen)
- && add_to_section (&sections[section], "", 1)))
- {
- syntax_error (filename, lnum, _("section too long"),
- NULL, NULL, NULL, NULL);
- error = 1;
- }
- }
- else if (vallen < sizeof val)
- val[vallen++] = c;
- else
- {
- syntax_error (filename, lnum, _("value too long"),
- NULL, NULL, NULL, NULL);
- error = 1;
- }
- break;
-
- case get_equals:
- case got_equals:
- case got_varname:
- break;
- }
- }
-
-#undef To_seq
-
- return !error;
-}
-
-/* Add some characters to a section's data. Return true if all the
- characters fit, or false if the section's size limit was exceeded.
- */
-static int
-add_to_section (struct sect *s, const char *str, unsigned int len)
-{
- if (s->cur + len > sizeof s->data)
- return 0;
- strncpy ((char *) s->data + s->cur, str, len);
- s->cur += len;
- return 1;
-}
-
-/* Translate from an action name to its numeric code. This uses the
- auto-generated array in key.c.
- */
-static int
-lookup_action (const char *actname)
-{
- int i;
-
- if (strcmp ("invalid", actname) == 0)
- return A_INVALID;
- for (i = 0; function_key_array[i].name != NULL; i++)
- if (strcmp (function_key_array[i].name, actname) == 0)
- return function_key_array[i].code;
- return -1;
-}
-
-/* Put an integer to an infokey file.
- Integers are stored as two bytes, low order first,
- in radix INFOKEY_RADIX.
- */
-static int
-putint (int i, FILE *fp)
-{
- return fputc (i % INFOKEY_RADIX, fp) != EOF
- && fputc ((i / INFOKEY_RADIX) % INFOKEY_RADIX, fp) != EOF;
-}
-
-/* Write an entire section to an infokey file. If the section is
- empty, simply omit it.
- */
-static int
-putsect (struct sect *s, int code, FILE *fp)
-{
- if (s->cur == 0)
- return 1;
- return fputc (code, fp) != EOF
- && putint (s->cur, fp)
- && fwrite (s->data, s->cur, 1, fp) == 1;
-}
-
-/* Write an entire infokey file, given an array containing its sections.
- */
-static int
-write_infokey_file (FILE *fp, struct sect *sections)
-{
- /* Get rid of sections with no effect. */
- if (sections[info].cur == 1 && sections[info].data[0] == 0)
- sections[info].cur = 0;
- if (sections[ea].cur == 1 && sections[ea].data[0] == 0)
- sections[ea].cur = 0;
-
- /* Write all parts of the file out in order (no lseeks),
- checking for errors all the way. */
- return fputc (INFOKEY_MAGIC_S0, fp) != EOF
- && fputc (INFOKEY_MAGIC_S1, fp) != EOF
- && fputc (INFOKEY_MAGIC_S2, fp) != EOF
- && fputc (INFOKEY_MAGIC_S3, fp) != EOF
- && fputs (VERSION, fp) != EOF
- && fputc ('\0', fp) != EOF
- && putsect (&sections[info], INFOKEY_SECTION_INFO, fp)
- && putsect (&sections[ea], INFOKEY_SECTION_EA, fp)
- && putsect (&sections[var], INFOKEY_SECTION_VAR, fp)
- && fputc (INFOKEY_MAGIC_E0, fp) != EOF
- && fputc (INFOKEY_MAGIC_E1, fp) != EOF
- && fputc (INFOKEY_MAGIC_E2, fp) != EOF
- && fputc (INFOKEY_MAGIC_E3, fp) != EOF;
-}
-
-
-/* Error handling. */
-
-/* Give the user a "syntax error" message in the form
- progname: "filename", line N: message
- */
-static void
-error_message (int error_code, const char *fmt,
- const void *a1, const void *a2, const void *a3, const void *a4)
-{
- fprintf (stderr, "%s: ", program_name);
- fprintf (stderr, fmt, a1, a2, a3, a4);
- if (error_code)
- fprintf (stderr, " - %s", strerror (error_code));
- fprintf (stderr, "\n");
-}
-
-/* Give the user a generic error message in the form
- progname: message
- */
-static void
-syntax_error (const char *filename,
- unsigned int linenum, const char *fmt,
- const void *a1, const void *a2, const void *a3, const void *a4)
-{
- fprintf (stderr, "%s: ", program_name);
- fprintf (stderr, _("\"%s\", line %u: "), filename, linenum);
- fprintf (stderr, fmt, a1, a2, a3, a4);
- fprintf (stderr, "\n");
-}
-
-/* Produce a gentle rtfm. */
-static void
-suggest_help (void)
-{
- fprintf (stderr, _("Try --help for more information.\n"));
-}
-
-/* Produce a scaled down description of the available options to Info. */
-static void
-short_help (void)
-{
- printf (_("\
-Usage: %s [OPTION]... [INPUT-FILE]\n\
-\n\
-Compile infokey source file to infokey file. Reads INPUT-FILE (default\n\
-$HOME/.infokey) and writes compiled key file to (by default) $HOME/.info.\n\
-\n\
-Options:\n\
- --output FILE output to FILE instead of $HOME/.info\n\
- --help display this help and exit.\n\
- --version display version information and exit.\n\
-"), program_name);
-
- puts (_("\n\
-Email bug reports to bug-texinfo@gnu.org,\n\
-general questions and discussion to help-texinfo@gnu.org.\n\
-Texinfo home page: http://www.gnu.org/software/texinfo/"));
-
- xexit (0);
-}