info.c revision 100513
142660Smarkm/* info.c -- Display nodes of Info files in multiple windows.
2100513Sru   $Id: info.c,v 1.60 2002/03/11 19:54:29 karl Exp $
321495Sjmacd
493139Sru   Copyright (C) 1993, 96, 97, 98, 99, 2000, 01, 02
593139Sru   Free Software Foundation, Inc.
621495Sjmacd
721495Sjmacd   This program is free software; you can redistribute it and/or modify
821495Sjmacd   it under the terms of the GNU General Public License as published by
921495Sjmacd   the Free Software Foundation; either version 2, or (at your option)
1021495Sjmacd   any later version.
1121495Sjmacd
1221495Sjmacd   This program is distributed in the hope that it will be useful,
1321495Sjmacd   but WITHOUT ANY WARRANTY; without even the implied warranty of
1421495Sjmacd   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1521495Sjmacd   GNU General Public License for more details.
1621495Sjmacd
1721495Sjmacd   You should have received a copy of the GNU General Public License
1821495Sjmacd   along with this program; if not, write to the Free Software
1921495Sjmacd   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2021495Sjmacd
2121495Sjmacd   Written by Brian Fox (bfox@ai.mit.edu). */
2221495Sjmacd
2321495Sjmacd#include "info.h"
2442660Smarkm#include "indices.h"
2521495Sjmacd#include "dribble.h"
2621495Sjmacd#include "getopt.h"
2721495Sjmacd#if defined (HANDLE_MAN_PAGES)
2821495Sjmacd#  include "man.h"
2921495Sjmacd#endif /* HANDLE_MAN_PAGES */
3021495Sjmacd
3156160Srustatic char *program_name = "info";
3221495Sjmacd
3321495Sjmacd/* Non-zero means search all indices for APROPOS_SEARCH_STRING. */
3421495Sjmacdstatic int apropos_p = 0;
3521495Sjmacd
3621495Sjmacd/* Variable containing the string to search for when apropos_p is non-zero. */
3721495Sjmacdstatic char *apropos_search_string = (char *)NULL;
3821495Sjmacd
3942660Smarkm/* Non-zero means search all indices for INDEX_SEARCH_STRING.  Unlike
4042660Smarkm   apropos, this puts the user at the node, running info. */
4142660Smarkmstatic int index_search_p = 0;
4242660Smarkm
4356160Sru/* Non-zero means look for the node which describes the invocation
4456160Sru   and command-line options of the program, and start the info
4556160Sru   session at that node.  */
4656160Srustatic int goto_invocation_p = 0;
4756160Sru
4842660Smarkm/* Variable containing the string to search for when index_search_p is
4956160Sru   non-zero. */
5042660Smarkmstatic char *index_search_string = (char *)NULL;
5142660Smarkm
5221495Sjmacd/* Non-zero means print version info only. */
5321495Sjmacdstatic int print_version_p = 0;
5421495Sjmacd
5521495Sjmacd/* Non-zero means print a short description of the options. */
5621495Sjmacdstatic int print_help_p = 0;
5721495Sjmacd
5821495Sjmacd/* Array of the names of nodes that the user specified with "--node" on the
5921495Sjmacd   command line. */
6021495Sjmacdstatic char **user_nodenames = (char **)NULL;
6121495Sjmacdstatic int user_nodenames_index = 0;
6221495Sjmacdstatic int user_nodenames_slots = 0;
6321495Sjmacd
6421495Sjmacd/* String specifying the first file to load.  This string can only be set
6521495Sjmacd   by the user specifying "--file" on the command line. */
6621495Sjmacdstatic char *user_filename = (char *)NULL;
6721495Sjmacd
6821495Sjmacd/* String specifying the name of the file to dump nodes to.  This value is
6921495Sjmacd   filled if the user speficies "--output" on the command line. */
7021495Sjmacdstatic char *user_output_filename = (char *)NULL;
7121495Sjmacd
7221495Sjmacd/* Non-zero indicates that when "--output" is specified, all of the menu
7321495Sjmacd   items of the specified nodes (and their subnodes as well) should be
7421495Sjmacd   dumped in the order encountered.  This basically can print a book. */
7521495Sjmacdint dump_subnodes = 0;
7621495Sjmacd
7756160Sru/* Non-zero means make default keybindings be loosely modeled on vi(1).  */
7856160Sruint vi_keys_p = 0;
7956160Sru
8093139Sru/* Non-zero means don't remove ANSI escape sequences from man pages.  */
8193139Sruint raw_escapes_p = 0;
8293139Sru
8356160Sru#ifdef __MSDOS__
8456160Sru/* Non-zero indicates that screen output should be made 'speech-friendly'.
8556160Sru   Since on MSDOS the usual behavior is to write directly to the video
8656160Sru   memory, speech synthesizer software cannot grab the output.  Therefore,
8756160Sru   we provide a user option which tells us to avoid direct screen output
8856160Sru   and use stdout instead (which loses the color output).  */
8956160Sruint speech_friendly = 0;
9056160Sru#endif
9156160Sru
9221495Sjmacd/* Structure describing the options that Info accepts.  We pass this structure
9321495Sjmacd   to getopt_long ().  If you add or otherwise change this structure, you must
9421495Sjmacd   also change the string which follows it. */
9521495Sjmacd#define APROPOS_OPTION 1
9621495Sjmacd#define DRIBBLE_OPTION 2
9721495Sjmacd#define RESTORE_OPTION 3
9842660Smarkm#define IDXSRCH_OPTION 4
9921495Sjmacdstatic struct option long_options[] = {
10021495Sjmacd  { "apropos", 1, 0, APROPOS_OPTION },
10121495Sjmacd  { "directory", 1, 0, 'd' },
102100513Sru  { "dribble", 1, 0, DRIBBLE_OPTION },
103100513Sru  { "file", 1, 0, 'f' },
104100513Sru  { "help", 0, &print_help_p, 1 },
105100513Sru  { "index-search", 1, 0, IDXSRCH_OPTION },
10621495Sjmacd  { "node", 1, 0, 'n' },
10721495Sjmacd  { "output", 1, 0, 'o' },
10893139Sru  { "raw-escapes", 0, &raw_escapes_p, 1 },
109100513Sru  { "restore", 1, 0, RESTORE_OPTION },
11056160Sru  { "show-options", 0, 0, 'O' },
111100513Sru  { "subnodes", 0, &dump_subnodes, 1 },
11256160Sru  { "usage", 0, 0, 'O' },
113100513Sru  { "version", 0, &print_version_p, 1 },
11456160Sru  { "vi-keys", 0, &vi_keys_p, 1 },
11556160Sru#ifdef __MSDOS__
11656160Sru  { "speech-friendly", 0, &speech_friendly, 1 },
11756160Sru#endif
11821495Sjmacd  {NULL, 0, NULL, 0}
11921495Sjmacd};
12021495Sjmacd
12121495Sjmacd/* String describing the shorthand versions of the long options found above. */
12256160Sru#ifdef __MSDOS__
12393139Srustatic char *short_options = "d:n:f:o:ORsb";
12456160Sru#else
12593139Srustatic char *short_options = "d:n:f:o:ORs";
12656160Sru#endif
12721495Sjmacd
12821495Sjmacd/* When non-zero, the Info window system has been initialized. */
12921495Sjmacdint info_windows_initialized_p = 0;
13021495Sjmacd
13121495Sjmacd/* Some "forward" declarations. */
13242660Smarkmstatic void info_short_help (), remember_info_program_name ();
13356160Srustatic void init_messages ();
13493139Sruextern void add_file_directory_to_path ();
13521495Sjmacd
13621495Sjmacd
13721495Sjmacd/* **************************************************************** */
13842660Smarkm/*                                                                  */
13942660Smarkm/*                Main Entry Point to the Info Program              */
14042660Smarkm/*                                                                  */
14121495Sjmacd/* **************************************************************** */
14221495Sjmacd
14321495Sjmacdint
14421495Sjmacdmain (argc, argv)
14521495Sjmacd     int argc;
14621495Sjmacd     char **argv;
14721495Sjmacd{
14842660Smarkm  int getopt_long_index;        /* Index returned by getopt_long (). */
14942660Smarkm  NODE *initial_node;           /* First node loaded by Info. */
15021495Sjmacd
15142660Smarkm#ifdef HAVE_SETLOCALE
15242660Smarkm  /* Set locale via LC_ALL.  */
15342660Smarkm  setlocale (LC_ALL, "");
15442660Smarkm#endif
15542660Smarkm
15642660Smarkm  /* Set the text message domain.  */
15742660Smarkm  bindtextdomain (PACKAGE, LOCALEDIR);
15842660Smarkm  textdomain (PACKAGE);
15942660Smarkm
16056160Sru  init_messages ();
16156160Sru
16221495Sjmacd  while (1)
16321495Sjmacd    {
16421495Sjmacd      int option_character;
16521495Sjmacd
16621495Sjmacd      option_character = getopt_long
16742660Smarkm        (argc, argv, short_options, long_options, &getopt_long_index);
16821495Sjmacd
16921495Sjmacd      /* getopt_long () returns EOF when there are no more long options. */
17021495Sjmacd      if (option_character == EOF)
17142660Smarkm        break;
17221495Sjmacd
17321495Sjmacd      /* If this is a long option, then get the short version of it. */
17421495Sjmacd      if (option_character == 0 && long_options[getopt_long_index].flag == 0)
17542660Smarkm        option_character = long_options[getopt_long_index].val;
17621495Sjmacd
17721495Sjmacd      /* Case on the option that we have received. */
17821495Sjmacd      switch (option_character)
17942660Smarkm        {
18042660Smarkm        case 0:
18142660Smarkm          break;
18221495Sjmacd
18342660Smarkm          /* User wants to add a directory. */
18442660Smarkm        case 'd':
18542660Smarkm          info_add_path (optarg, INFOPATH_PREPEND);
18642660Smarkm          break;
18721495Sjmacd
18842660Smarkm          /* User is specifying a particular node. */
18942660Smarkm        case 'n':
19042660Smarkm          add_pointer_to_array (optarg, user_nodenames_index, user_nodenames,
19142660Smarkm                                user_nodenames_slots, 10, char *);
19242660Smarkm          break;
19321495Sjmacd
19442660Smarkm          /* User is specifying a particular Info file. */
19542660Smarkm        case 'f':
19642660Smarkm          if (user_filename)
19742660Smarkm            free (user_filename);
19821495Sjmacd
19942660Smarkm          user_filename = xstrdup (optarg);
20042660Smarkm          break;
20121495Sjmacd
20242660Smarkm          /* User is specifying the name of a file to output to. */
20342660Smarkm        case 'o':
20442660Smarkm          if (user_output_filename)
20542660Smarkm            free (user_output_filename);
20642660Smarkm          user_output_filename = xstrdup (optarg);
20742660Smarkm          break;
20821495Sjmacd
20956160Sru         /* User has specified that she wants to find the "Options"
21056160Sru             or "Invocation" node for the program.  */
21156160Sru        case 'O':
21256160Sru          goto_invocation_p = 1;
21356160Sru          break;
21456160Sru
21593139Sru	  /* User has specified that she wants the escape sequences
21693139Sru	     in man pages to be passed thru unaltered.  */
21793139Sru        case 'R':
21893139Sru          raw_escapes_p = 1;
21993139Sru          break;
22093139Sru
22142660Smarkm          /* User is specifying that she wishes to dump the subnodes of
22242660Smarkm             the node that she is dumping. */
22342660Smarkm        case 's':
22442660Smarkm          dump_subnodes = 1;
22542660Smarkm          break;
22621495Sjmacd
22756160Sru#ifdef __MSDOS__
22893139Sru	  /* User wants speech-friendly output.  */
22956160Sru	case 'b':
23056160Sru	  speech_friendly = 1;
23156160Sru	  break;
23256160Sru#endif /* __MSDOS__ */
23356160Sru
23442660Smarkm          /* User has specified a string to search all indices for. */
23542660Smarkm        case APROPOS_OPTION:
23642660Smarkm          apropos_p = 1;
23742660Smarkm          maybe_free (apropos_search_string);
23842660Smarkm          apropos_search_string = xstrdup (optarg);
23942660Smarkm          break;
24021495Sjmacd
24142660Smarkm          /* User has specified a dribble file to receive keystrokes. */
24242660Smarkm        case DRIBBLE_OPTION:
24342660Smarkm          close_dribble_file ();
24442660Smarkm          open_dribble_file (optarg);
24542660Smarkm          break;
24621495Sjmacd
24742660Smarkm          /* User has specified an alternate input stream. */
24842660Smarkm        case RESTORE_OPTION:
24942660Smarkm          info_set_input_from_file (optarg);
25042660Smarkm          break;
25121495Sjmacd
25242660Smarkm          /* User has specified a string to search all indices for. */
25342660Smarkm        case IDXSRCH_OPTION:
25442660Smarkm          index_search_p = 1;
25542660Smarkm          maybe_free (index_search_string);
25642660Smarkm          index_search_string = xstrdup (optarg);
25742660Smarkm          break;
25842660Smarkm
25942660Smarkm        default:
26056160Sru          fprintf (stderr, _("Try --help for more information.\n"));
26156160Sru          xexit (1);
26242660Smarkm        }
26321495Sjmacd    }
26421495Sjmacd
26521495Sjmacd  /* If the output device is not a terminal, and no output filename has been
26621495Sjmacd     specified, make user_output_filename be "-", so that the info is written
26721495Sjmacd     to stdout, and turn on the dumping of subnodes. */
26821495Sjmacd  if ((!isatty (fileno (stdout))) && (user_output_filename == (char *)NULL))
26921495Sjmacd    {
27042660Smarkm      user_output_filename = xstrdup ("-");
27121495Sjmacd      dump_subnodes = 1;
27221495Sjmacd    }
27321495Sjmacd
27421495Sjmacd  /* If the user specified --version, then show the version and exit. */
27521495Sjmacd  if (print_version_p)
27621495Sjmacd    {
27756160Sru      printf ("%s (GNU %s) %s\n", program_name, PACKAGE, VERSION);
27856160Sru      puts ("");
27942660Smarkm      printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
28021495SjmacdThere is NO warranty.  You may redistribute this software\n\
28121495Sjmacdunder the terms of the GNU General Public License.\n\
28242660SmarkmFor more information about these matters, see the files named COPYING.\n"),
28393139Sru		  "2002");
28456160Sru      xexit (0);
28521495Sjmacd    }
28621495Sjmacd
28721495Sjmacd  /* If the `--help' option was present, show the help and exit. */
28821495Sjmacd  if (print_help_p)
28921495Sjmacd    {
29021495Sjmacd      info_short_help ();
29156160Sru      xexit (0);
29221495Sjmacd    }
29356160Sru
29442660Smarkm  /* If the user hasn't specified a path for Info files, default it.
29542660Smarkm     Lowest priority is our messy hardwired list in filesys.h.
29642660Smarkm     Then comes the user's INFODIR from the Makefile.
29742660Smarkm     Highest priority is the environment variable, if set.  */
29821495Sjmacd  if (!infopath)
29921495Sjmacd    {
30042660Smarkm      char *path_from_env = getenv ("INFOPATH");
30121495Sjmacd
30221495Sjmacd      if (path_from_env)
30342660Smarkm        {
30442660Smarkm          unsigned len = strlen (path_from_env);
30542660Smarkm          /* Trailing : on INFOPATH means insert the default path.  */
30656160Sru          if (len && path_from_env[len - 1] == PATH_SEP[0])
30742660Smarkm            {
30842660Smarkm              path_from_env[len - 1] = 0;
30942660Smarkm              info_add_path (DEFAULT_INFOPATH, INFOPATH_PREPEND);
31042660Smarkm            }
31142660Smarkm#ifdef INFODIR /* from the Makefile */
31242660Smarkm          info_add_path (INFODIR, INFOPATH_PREPEND);
31342660Smarkm#endif
31442660Smarkm          info_add_path (path_from_env, INFOPATH_PREPEND);
31542660Smarkm        }
31621495Sjmacd      else
31742660Smarkm        {
31842660Smarkm          info_add_path (DEFAULT_INFOPATH, INFOPATH_PREPEND);
31942660Smarkm#ifdef INFODIR /* from the Makefile */
32042660Smarkm         info_add_path (INFODIR, INFOPATH_PREPEND);
32142660Smarkm#endif
32242660Smarkm        }
32321495Sjmacd    }
32421495Sjmacd
32521495Sjmacd  /* If the user specified a particular filename, add the path of that
32621495Sjmacd     file to the contents of INFOPATH. */
32721495Sjmacd  if (user_filename)
32893139Sru    add_file_directory_to_path (user_filename);
32921495Sjmacd
33021495Sjmacd  /* If the user wants to search every known index for a given string,
33121495Sjmacd     do that now, and report the results. */
33221495Sjmacd  if (apropos_p)
33321495Sjmacd    {
33421495Sjmacd      info_apropos (apropos_search_string);
33556160Sru      xexit (0);
33621495Sjmacd    }
33721495Sjmacd
33821495Sjmacd  /* Get the initial Info node.  It is either "(dir)Top", or what the user
33921495Sjmacd     specifed with values in user_filename and user_nodenames. */
34042660Smarkm  initial_node = info_get_node (user_filename,
34156160Sru                                user_nodenames ? user_nodenames[0] : 0);
34221495Sjmacd
34321495Sjmacd  /* If we couldn't get the initial node, this user is in trouble. */
34421495Sjmacd  if (!initial_node)
34521495Sjmacd    {
34621495Sjmacd      if (info_recent_file_error)
34742660Smarkm        info_error (info_recent_file_error);
34821495Sjmacd      else
34956160Sru        info_error (msg_cant_find_node,
35056160Sru                    user_nodenames ? user_nodenames[0] : "Top");
35156160Sru      xexit (1);
35221495Sjmacd    }
35321495Sjmacd
35442660Smarkm  /* Special cases for when the user specifies multiple nodes.  If we
35542660Smarkm     are dumping to an output file, dump all of the nodes specified.
35642660Smarkm     Otherwise, attempt to create enough windows to handle the nodes
35742660Smarkm     that this user wants displayed. */
35821495Sjmacd  if (user_nodenames_index > 1)
35921495Sjmacd    {
36021495Sjmacd      free (initial_node);
36121495Sjmacd
36221495Sjmacd      if (user_output_filename)
36342660Smarkm        dump_nodes_to_file
36442660Smarkm          (user_filename, user_nodenames, user_output_filename, dump_subnodes);
36521495Sjmacd      else
36642660Smarkm        begin_multiple_window_info_session (user_filename, user_nodenames);
36721495Sjmacd
36856160Sru      xexit (0);
36921495Sjmacd    }
37021495Sjmacd
37121495Sjmacd  /* If there are arguments remaining, they are the names of menu items
37221495Sjmacd     in sequential info files starting from the first one loaded.  That
37321495Sjmacd     file name is either "dir", or the contents of user_filename if one
37421495Sjmacd     was specified. */
37556160Sru  {
37656160Sru    char *errstr, *errarg1, *errarg2;
37756160Sru    NODE *new_initial_node = info_follow_menus (initial_node, argv + optind,
37856160Sru                                                &errstr, &errarg1, &errarg2);
37993139Sru
38056160Sru    if (new_initial_node && new_initial_node != initial_node)
38156160Sru      initial_node = new_initial_node;
38221495Sjmacd
38356160Sru    /* If the user specified that this node should be output, then do that
38456160Sru       now.  Otherwise, start the Info session with this node.  Or act
38556160Sru       accordingly if the initial node was not found.  */
38693139Sru    if (user_output_filename && !goto_invocation_p)
38756160Sru      {
38856160Sru        if (!errstr)
38956160Sru          dump_node_to_file (initial_node, user_output_filename,
39056160Sru                             dump_subnodes);
39156160Sru        else
39256160Sru          info_error (errstr, errarg1, errarg2);
39356160Sru      }
39456160Sru    else
39556160Sru      {
39621495Sjmacd
39756160Sru        if (errstr)
39856160Sru          begin_info_session_with_error (initial_node, errstr,
39956160Sru                                         errarg1, errarg2);
40056160Sru        /* If the user specified `--index-search=STRING' or
40156160Sru           --show-options, start the info session in the node
40256160Sru           corresponding to what they want. */
40356160Sru        else if (index_search_p || goto_invocation_p)
40456160Sru          {
40556160Sru            int status = 0;
40621495Sjmacd
40756160Sru            initialize_info_session (initial_node, 0);
40821495Sjmacd
40956160Sru            if (goto_invocation_p
41056160Sru                || index_entry_exists (windows, index_search_string))
41156160Sru              {
41256160Sru                terminal_prep_terminal ();
41356160Sru                terminal_clear_screen ();
41456160Sru                info_last_executed_command = (VFunction *)NULL;
41521495Sjmacd
41656160Sru                if (index_search_p)
41756160Sru                  do_info_index_search (windows, 0, index_search_string);
41856160Sru                else
41956160Sru                  {
42056160Sru                    /* If they said "info --show-options foo bar baz",
42156160Sru                       the last of the arguments is the program whose
42256160Sru                       options they want to see.  */
42356160Sru                    char **p = argv + optind;
42456160Sru                    char *program;
42521495Sjmacd
42656160Sru                    if (*p)
42756160Sru                      {
42856160Sru                        while (p[1])
42956160Sru                          p++;
43056160Sru                        program = xstrdup (*p);
43156160Sru                      }
43256160Sru                    else if (user_filename)
43356160Sru		      /* If there's no command-line arguments to
43456160Sru			 supply the program name, use the Info file
43556160Sru			 name (sans extension and leading directories)
43656160Sru			 instead.  */
43756160Sru		      program = program_name_from_file_name (user_filename);
43856160Sru		    else
43956160Sru		      program = xstrdup ("");
44021495Sjmacd
44156160Sru                    info_intuit_options_node (windows, initial_node, program);
44256160Sru                    free (program);
44356160Sru                  }
44421495Sjmacd
44593139Sru		if (user_output_filename)
44693139Sru		  {
44793139Sru		    dump_node_to_file (windows->node, user_output_filename,
44893139Sru				       dump_subnodes);
44993139Sru		  }
45093139Sru		else
45193139Sru		  info_read_and_dispatch ();
45221495Sjmacd
45356160Sru                /* On program exit, leave the cursor at the bottom of the
45456160Sru                   window, and restore the terminal IO. */
45556160Sru                terminal_goto_xy (0, screenheight - 1);
45656160Sru                terminal_clear_to_eol ();
45756160Sru                fflush (stdout);
45856160Sru                terminal_unprep_terminal ();
45956160Sru              }
46056160Sru            else
46156160Sru              {
46256160Sru                fprintf (stderr, _("no index entries found for `%s'\n"),
46356160Sru                         index_search_string);
46456160Sru                status = 2;
46556160Sru              }
46621495Sjmacd
46756160Sru            close_dribble_file ();
46856160Sru            xexit (status);
46956160Sru          }
47056160Sru        else
47156160Sru          begin_info_session (initial_node);
47256160Sru      }
47321495Sjmacd
47456160Sru    xexit (0);
47556160Sru  }
47621495Sjmacd}
47721495Sjmacd
47893139Sruvoid
47993139Sruadd_file_directory_to_path (filename)
48093139Sru     char *filename;
48193139Sru{
48293139Sru  char *directory_name = xstrdup (filename);
48393139Sru  char *temp = filename_non_directory (directory_name);
48493139Sru
48593139Sru  if (temp != directory_name)
48693139Sru    {
48793139Sru      if (HAVE_DRIVE (directory_name) && temp == directory_name + 2)
48893139Sru	{
48993139Sru	  /* The directory of "d:foo" is stored as "d:.", to avoid
49093139Sru	     mixing it with "d:/" when a slash is appended.  */
49193139Sru	  *temp = '.';
49293139Sru	  temp += 2;
49393139Sru	}
49493139Sru      temp[-1] = 0;
49593139Sru      info_add_path (directory_name, INFOPATH_PREPEND);
49693139Sru    }
49793139Sru
49893139Sru  free (directory_name);
49993139Sru}
50093139Sru
50121495Sjmacd
50242660Smarkm/* Error handling.  */
50321495Sjmacd
50421495Sjmacd/* Non-zero if an error has been signalled. */
50521495Sjmacdint info_error_was_printed = 0;
50621495Sjmacd
50721495Sjmacd/* Non-zero means ring terminal bell on errors. */
50821495Sjmacdint info_error_rings_bell_p = 1;
50921495Sjmacd
51021495Sjmacd/* Print FORMAT with ARG1 and ARG2.  If the window system was initialized,
51121495Sjmacd   then the message is printed in the echo area.  Otherwise, a message is
51221495Sjmacd   output to stderr. */
51321495Sjmacdvoid
51421495Sjmacdinfo_error (format, arg1, arg2)
51521495Sjmacd     char *format;
51621495Sjmacd     void *arg1, *arg2;
51721495Sjmacd{
51821495Sjmacd  info_error_was_printed = 1;
51921495Sjmacd
52021495Sjmacd  if (!info_windows_initialized_p || display_inhibited)
52121495Sjmacd    {
52221495Sjmacd      fprintf (stderr, "%s: ", program_name);
52321495Sjmacd      fprintf (stderr, format, arg1, arg2);
52421495Sjmacd      fprintf (stderr, "\n");
52521495Sjmacd      fflush (stderr);
52621495Sjmacd    }
52721495Sjmacd  else
52821495Sjmacd    {
52921495Sjmacd      if (!echo_area_is_active)
53042660Smarkm        {
53142660Smarkm          if (info_error_rings_bell_p)
53242660Smarkm            terminal_ring_bell ();
53342660Smarkm          window_message_in_echo_area (format, arg1, arg2);
53442660Smarkm        }
53521495Sjmacd      else
53642660Smarkm        {
53742660Smarkm          NODE *temp;
53821495Sjmacd
53942660Smarkm          temp = build_message_node (format, arg1, arg2);
54042660Smarkm          if (info_error_rings_bell_p)
54142660Smarkm            terminal_ring_bell ();
54242660Smarkm          inform_in_echo_area (temp->contents);
54342660Smarkm          free (temp->contents);
54442660Smarkm          free (temp);
54542660Smarkm        }
54621495Sjmacd    }
54721495Sjmacd}
54821495Sjmacd
54956160Sru
55021495Sjmacd/* Produce a scaled down description of the available options to Info. */
55121495Sjmacdstatic void
55221495Sjmacdinfo_short_help ()
55321495Sjmacd{
55493139Sru#ifdef __MSDOS__
55593139Sru  static const char speech_friendly_string[] = N_("\
556100513Sru  -b, --speech-friendly        be friendly to speech synthesizers.\n");
55793139Sru#else
55893139Sru  static const char speech_friendly_string[] = "";
55993139Sru#endif
56093139Sru
56193139Sru
56242660Smarkm  printf (_("\
56356160SruUsage: %s [OPTION]... [MENU-ITEM...]\n\
56421495Sjmacd\n\
56542660SmarkmRead documentation in Info format.\n\
56621495Sjmacd\n\
56742660SmarkmOptions:\n\
568100513Sru      --apropos=STRING         look up STRING in all indices of all manuals.\n\
569100513Sru  -d, --directory=DIR          add DIR to INFOPATH.\n\
570100513Sru      --dribble=FILENAME       remember user keystrokes in FILENAME.\n\
571100513Sru  -f, --file=FILENAME          specify Info file to visit.\n\
572100513Sru  -h, --help                   display this help and exit.\n\
573100513Sru      --index-search=STRING    go to node pointed by index entry STRING.\n\
574100513Sru  -n, --node=NODENAME          specify nodes in first visited Info file.\n\
575100513Sru  -o, --output=FILENAME        output selected nodes to FILENAME.\n\
576100513Sru  -R, --raw-escapes            don't remove ANSI escapes from man pages.\n\
577100513Sru      --restore=FILENAME       read initial keystrokes from FILENAME.\n\
578100513Sru  -O, --show-options, --usage  go to command-line options node.\n%s\
579100513Sru      --subnodes               recursively output menu items.\n\
580100513Sru      --vi-keys                use vi-like and less-like key bindings.\n\
581100513Sru      --version                display version information and exit.\n\
58221495Sjmacd\n\
58356160SruThe first non-option argument, if present, is the menu entry to start from;\n\
58456160Sruit is searched for in all `dir' files along INFOPATH.\n\
58556160SruIf it is not present, info merges all `dir' files and shows the result.\n\
58642660SmarkmAny remaining arguments are treated as the names of menu\n\
58756160Sruitems relative to the initial node visited.\n\
58842660Smarkm\n\
58956160SruExamples:\n\
59056160Sru  info                       show top-level dir menu\n\
59156160Sru  info emacs                 start at emacs node from top-level dir\n\
59256160Sru  info emacs buffers         start at buffers node within emacs manual\n\
59356160Sru  info --show-options emacs  start at node with emacs' command line options\n\
59456160Sru  info -f ./foo.info         show file ./foo.info, not searching dir\n\
59556160Sru"),
59693139Sru  program_name, speech_friendly_string);
59721495Sjmacd
598100513Sru  puts (_("\n\
599100513SruEmail bug reports to bug-texinfo@gnu.org,\n\
600100513Srugeneral questions and discussion to help-texinfo@gnu.org.\n\
601100513SruTexinfo home page: http://www.gnu.org/software/texinfo/"));
602100513Sru
60356160Sru  xexit (0);
60421495Sjmacd}
60556160Sru
60656160Sru
60756160Sru/* Initialize strings for gettext.  Because gettext doesn't handle N_ or
60856160Sru   _ within macro definitions, we put shared messages into variables and
60956160Sru   use them that way.  This also has the advantage that there's only one
61056160Sru   copy of the strings.  */
61156160Sru
61256160Sruchar *msg_cant_find_node;
61356160Sruchar *msg_cant_file_node;
61456160Sruchar *msg_cant_find_window;
61556160Sruchar *msg_cant_find_point;
61656160Sruchar *msg_cant_kill_last;
61756160Sruchar *msg_no_menu_node;
61856160Sruchar *msg_no_foot_node;
61956160Sruchar *msg_no_xref_node;
62056160Sruchar *msg_no_pointer;
62156160Sruchar *msg_unknown_command;
62256160Sruchar *msg_term_too_dumb;
62356160Sruchar *msg_at_node_bottom;
62456160Sruchar *msg_at_node_top;
62556160Sruchar *msg_one_window;
62656160Sruchar *msg_win_too_small;
62756160Sruchar *msg_cant_make_help;
62856160Sru
62956160Srustatic void
63056160Sruinit_messages ()
63156160Sru{
63256160Sru  msg_cant_find_node   = _("Cannot find node `%s'.");
63356160Sru  msg_cant_file_node   = _("Cannot find node `(%s)%s'.");
63456160Sru  msg_cant_find_window = _("Cannot find a window!");
63556160Sru  msg_cant_find_point  = _("Point doesn't appear within this window's node!");
63656160Sru  msg_cant_kill_last   = _("Cannot delete the last window.");
63756160Sru  msg_no_menu_node     = _("No menu in this node.");
63856160Sru  msg_no_foot_node     = _("No footnotes in this node.");
63956160Sru  msg_no_xref_node     = _("No cross references in this node.");
64056160Sru  msg_no_pointer       = _("No `%s' pointer for this node.");
64156160Sru  msg_unknown_command  = _("Unknown Info command `%c'; try `?' for help.");
64256160Sru  msg_term_too_dumb    = _("Terminal type `%s' is not smart enough to run Info.");
64356160Sru  msg_at_node_bottom   = _("You are already at the last page of this node.");
64456160Sru  msg_at_node_top      = _("You are already at the first page of this node.");
64556160Sru  msg_one_window       = _("Only one window.");
64656160Sru  msg_win_too_small    = _("Resulting window would be too small.");
64756160Sru  msg_cant_make_help   = _("Not enough room for a help window, please delete a window.");
64856160Sru}
649