Back to index

tetex-bin  3.0
info.c
Go to the documentation of this file.
00001 /* info.c -- Display nodes of Info files in multiple windows.
00002    $Id: info.c,v 1.11 2004/04/11 17:56:45 karl Exp $
00003 
00004    Copyright (C) 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
00005    2004 Free Software Foundation, Inc.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2, or (at your option)
00010    any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00020 
00021    Written by Brian Fox (bfox@ai.mit.edu). */
00022 
00023 #include "info.h"
00024 #include "indices.h"
00025 #include "dribble.h"
00026 #include "getopt.h"
00027 #if defined (HANDLE_MAN_PAGES)
00028 #  include "man.h"
00029 #endif /* HANDLE_MAN_PAGES */
00030 
00031 static char *program_name = "info";
00032 
00033 /* Non-zero means search all indices for APROPOS_SEARCH_STRING. */
00034 static int apropos_p = 0;
00035 
00036 /* Variable containing the string to search for when apropos_p is non-zero. */
00037 static char *apropos_search_string = (char *)NULL;
00038 
00039 /* Non-zero means search all indices for INDEX_SEARCH_STRING.  Unlike
00040    apropos, this puts the user at the node, running info. */
00041 static int index_search_p = 0;
00042 
00043 /* Non-zero means look for the node which describes the invocation
00044    and command-line options of the program, and start the info
00045    session at that node.  */
00046 static int goto_invocation_p = 0;
00047 
00048 /* Variable containing the string to search for when index_search_p is
00049    non-zero. */
00050 static char *index_search_string = (char *)NULL;
00051 
00052 /* Non-zero means print version info only. */
00053 static int print_version_p = 0;
00054 
00055 /* Non-zero means print a short description of the options. */
00056 static int print_help_p = 0;
00057 
00058 /* Array of the names of nodes that the user specified with "--node" on the
00059    command line. */
00060 static char **user_nodenames = (char **)NULL;
00061 static int user_nodenames_index = 0;
00062 static int user_nodenames_slots = 0;
00063 
00064 /* String specifying the first file to load.  This string can only be set
00065    by the user specifying "--file" on the command line. */
00066 static char *user_filename = (char *)NULL;
00067 
00068 /* String specifying the name of the file to dump nodes to.  This value is
00069    filled if the user speficies "--output" on the command line. */
00070 static char *user_output_filename = (char *)NULL;
00071 
00072 /* Non-zero indicates that when "--output" is specified, all of the menu
00073    items of the specified nodes (and their subnodes as well) should be
00074    dumped in the order encountered.  This basically can print a book. */
00075 int dump_subnodes = 0;
00076 
00077 /* Non-zero means make default keybindings be loosely modeled on vi(1).  */
00078 int vi_keys_p = 0;
00079 
00080 /* Non-zero means don't remove ANSI escape sequences.  */
00081 int raw_escapes_p = 1;
00082 
00083 /* Non-zero means print the absolute location of the file to be loaded.  */
00084 static int print_where_p = 0;
00085 
00086 #ifdef __MSDOS__
00087 /* Non-zero indicates that screen output should be made 'speech-friendly'.
00088    Since on MSDOS the usual behavior is to write directly to the video
00089    memory, speech synthesizer software cannot grab the output.  Therefore,
00090    we provide a user option which tells us to avoid direct screen output
00091    and use stdout instead (which loses the color output).  */
00092 int speech_friendly = 0;
00093 #endif
00094 
00095 /* Structure describing the options that Info accepts.  We pass this structure
00096    to getopt_long ().  If you add or otherwise change this structure, you must
00097    also change the string which follows it. */
00098 #define APROPOS_OPTION 1
00099 #define DRIBBLE_OPTION 2
00100 #define RESTORE_OPTION 3
00101 #define IDXSRCH_OPTION 4
00102 static struct option long_options[] = {
00103   { "apropos", 1, 0, APROPOS_OPTION },
00104   { "directory", 1, 0, 'd' },
00105   { "dribble", 1, 0, DRIBBLE_OPTION },
00106   { "file", 1, 0, 'f' },
00107   { "help", 0, &print_help_p, 1 },
00108   { "index-search", 1, 0, IDXSRCH_OPTION },
00109   { "location", 0, &print_where_p, 1 },
00110   { "node", 1, 0, 'n' },
00111   { "output", 1, 0, 'o' },
00112   { "raw-escapes", 0, &raw_escapes_p, 1 },
00113   { "no-raw-escapes", 0, &raw_escapes_p, 0 },
00114   { "restore", 1, 0, RESTORE_OPTION },
00115   { "show-options", 0, 0, 'O' },
00116   { "subnodes", 0, &dump_subnodes, 1 },
00117   { "usage", 0, 0, 'O' },
00118   { "version", 0, &print_version_p, 1 },
00119   { "vi-keys", 0, &vi_keys_p, 1 },
00120   { "where", 0, &print_where_p, 1 },
00121 #ifdef __MSDOS__
00122   { "speech-friendly", 0, &speech_friendly, 1 },
00123 #endif
00124   {NULL, 0, NULL, 0}
00125 };
00126 
00127 /* String describing the shorthand versions of the long options found above. */
00128 #ifdef __MSDOS__
00129 static char *short_options = "d:n:f:ho:ORswb";
00130 #else
00131 static char *short_options = "d:n:f:ho:ORws";
00132 #endif
00133 
00134 /* When non-zero, the Info window system has been initialized. */
00135 int info_windows_initialized_p = 0;
00136 
00137 /* Some "forward" declarations. */
00138 static void info_short_help (void);
00139 static void init_messages (void);
00140 
00141 
00142 /* **************************************************************** */
00143 /*                                                                  */
00144 /*                Main Entry Point to the Info Program              */
00145 /*                                                                  */
00146 /* **************************************************************** */
00147 
00148 int
00149 main (int argc, char **argv)
00150 {
00151   int getopt_long_index;        /* Index returned by getopt_long (). */
00152   NODE *initial_node;           /* First node loaded by Info. */
00153 
00154 #ifdef HAVE_SETLOCALE
00155   /* Set locale via LC_ALL.  */
00156   setlocale (LC_ALL, "");
00157 #endif
00158 
00159 #ifdef ENABLE_NLS
00160   /* Set the text message domain.  */
00161   bindtextdomain (PACKAGE, LOCALEDIR);
00162   textdomain (PACKAGE);
00163 #endif
00164 
00165   init_messages ();
00166 
00167   while (1)
00168     {
00169       int option_character;
00170 
00171       option_character = getopt_long
00172         (argc, argv, short_options, long_options, &getopt_long_index);
00173 
00174       /* getopt_long returns EOF when there are no more long options. */
00175       if (option_character == EOF)
00176         break;
00177 
00178       /* If this is a long option, then get the short version of it. */
00179       if (option_character == 0 && long_options[getopt_long_index].flag == 0)
00180         option_character = long_options[getopt_long_index].val;
00181 
00182       /* Case on the option that we have received. */
00183       switch (option_character)
00184         {
00185         case 0:
00186           break;
00187 
00188           /* User wants to add a directory. */
00189         case 'd':
00190           info_add_path (optarg, INFOPATH_PREPEND);
00191           break;
00192 
00193           /* User is specifying a particular node. */
00194         case 'n':
00195           add_pointer_to_array (optarg, user_nodenames_index, user_nodenames,
00196                                 user_nodenames_slots, 10, char *);
00197           break;
00198 
00199           /* User is specifying a particular Info file. */
00200         case 'f':
00201           if (user_filename)
00202             free (user_filename);
00203 
00204           user_filename = xstrdup (optarg);
00205           break;
00206 
00207           /* Treat -h like --help. */
00208         case 'h':
00209           print_help_p = 1;
00210           break;
00211 
00212           /* User is specifying the name of a file to output to. */
00213         case 'o':
00214           if (user_output_filename)
00215             free (user_output_filename);
00216           user_output_filename = xstrdup (optarg);
00217           break;
00218 
00219          /* User has specified that she wants to find the "Options"
00220              or "Invocation" node for the program.  */
00221         case 'O':
00222           goto_invocation_p = 1;
00223           break;
00224 
00225          /* User has specified that she wants the escape sequences
00226             in man pages to be passed thru unaltered.  */
00227         case 'R':
00228           raw_escapes_p = 1;
00229           break;
00230 
00231           /* User is specifying that she wishes to dump the subnodes of
00232              the node that she is dumping. */
00233         case 's':
00234           dump_subnodes = 1;
00235           break;
00236 
00237           /* For compatibility with man, -w is --where.  */
00238         case 'w':
00239           print_where_p = 1;
00240           break;
00241 
00242 #ifdef __MSDOS__
00243          /* User wants speech-friendly output.  */
00244        case 'b':
00245          speech_friendly = 1;
00246          break;
00247 #endif /* __MSDOS__ */
00248 
00249           /* User has specified a string to search all indices for. */
00250         case APROPOS_OPTION:
00251           apropos_p = 1;
00252           maybe_free (apropos_search_string);
00253           apropos_search_string = xstrdup (optarg);
00254           break;
00255 
00256           /* User has specified a dribble file to receive keystrokes. */
00257         case DRIBBLE_OPTION:
00258           close_dribble_file ();
00259           open_dribble_file (optarg);
00260           break;
00261 
00262           /* User has specified an alternate input stream. */
00263         case RESTORE_OPTION:
00264           info_set_input_from_file (optarg);
00265           break;
00266 
00267           /* User has specified a string to search all indices for. */
00268         case IDXSRCH_OPTION:
00269           index_search_p = 1;
00270           maybe_free (index_search_string);
00271           index_search_string = xstrdup (optarg);
00272           break;
00273 
00274         default:
00275           fprintf (stderr, _("Try --help for more information.\n"));
00276           xexit (1);
00277         }
00278     }
00279 
00280   /* If the output device is not a terminal, and no output filename has been
00281      specified, make user_output_filename be "-", so that the info is written
00282      to stdout, and turn on the dumping of subnodes. */
00283   if ((!isatty (fileno (stdout))) && (user_output_filename == (char *)NULL))
00284     {
00285       user_output_filename = xstrdup ("-");
00286       dump_subnodes = 1;
00287     }
00288 
00289   /* If the user specified --version, then show the version and exit. */
00290   if (print_version_p)
00291     {
00292       printf ("%s (GNU %s) %s\n", program_name, PACKAGE, VERSION);
00293       puts ("");
00294       puts ("Copyright (C) 2004 Free Software Foundation, Inc.");
00295       printf (_("There is NO warranty.  You may redistribute this software\n\
00296 under the terms of the GNU General Public License.\n\
00297 For more information about these matters, see the files named COPYING.\n"));
00298       xexit (0);
00299     }
00300 
00301   /* If the `--help' option was present, show the help and exit. */
00302   if (print_help_p)
00303     {
00304       info_short_help ();
00305       xexit (0);
00306     }
00307 
00308   /* If the user hasn't specified a path for Info files, default it.
00309      Lowest priority is our messy hardwired list in filesys.h.
00310      Then comes the user's INFODIR from the Makefile.
00311      Highest priority is the environment variable, if set.  */
00312   if (!infopath)
00313     {
00314       char *path_from_env = getenv ("INFOPATH");
00315 
00316       if (path_from_env)
00317         {
00318           unsigned len = strlen (path_from_env);
00319           /* Trailing : on INFOPATH means insert the default path.  */
00320           if (len && path_from_env[len - 1] == PATH_SEP[0])
00321             {
00322               path_from_env[len - 1] = 0;
00323               info_add_path (DEFAULT_INFOPATH, INFOPATH_PREPEND);
00324             }
00325 #ifdef INFODIR /* from the Makefile */
00326           info_add_path (INFODIR, INFOPATH_PREPEND);
00327 #endif
00328           info_add_path (path_from_env, INFOPATH_PREPEND);
00329         }
00330       else
00331         {
00332           info_add_path (DEFAULT_INFOPATH, INFOPATH_PREPEND);
00333 #ifdef INFODIR /* from the Makefile */
00334           info_add_path (INFODIR, INFOPATH_PREPEND);
00335 #endif
00336 #ifdef INFODIR2 /* from the Makefile, too */
00337 #  ifdef INFODIR
00338           if (!STREQ (INFODIR, INFODIR2))
00339 #  endif
00340             info_add_path (INFODIR2, INFOPATH_PREPEND);
00341 #endif
00342         }
00343     }
00344 
00345   /* If the user specified a particular filename, add the path of that
00346      file to the contents of INFOPATH. */
00347   if (user_filename)
00348     add_file_directory_to_path (user_filename);
00349 
00350   /* If the user wants to search every known index for a given string,
00351      do that now, and report the results. */
00352   if (apropos_p)
00353     {
00354       info_apropos (apropos_search_string);
00355       xexit (0);
00356     }
00357 
00358   /* Get the initial Info node.  It is either "(dir)Top", or what the user
00359      specifed with values in user_filename and user_nodenames. */
00360   initial_node = info_get_node (user_filename,
00361                                 user_nodenames ? user_nodenames[0] : 0);
00362 
00363   /* If we couldn't get the initial node, this user is in trouble. */
00364   if (!initial_node)
00365     {
00366       if (info_recent_file_error)
00367         info_error (info_recent_file_error, NULL, NULL);
00368       else
00369         info_error ((char *) msg_cant_find_node,
00370                     user_nodenames ? user_nodenames[0] : "Top", NULL);
00371       xexit (1);
00372     }
00373 
00374   /* Special cases for when the user specifies multiple nodes.  If we
00375      are dumping to an output file, dump all of the nodes specified.
00376      Otherwise, attempt to create enough windows to handle the nodes
00377      that this user wants displayed. */
00378   if (user_nodenames_index > 1)
00379     {
00380       free (initial_node);
00381 
00382       if (print_where_p)
00383         printf ("%s\n", user_filename ? user_filename : "unknown?!");
00384       else if (user_output_filename)
00385         dump_nodes_to_file
00386           (user_filename, user_nodenames, user_output_filename, dump_subnodes);
00387       else
00388         begin_multiple_window_info_session (user_filename, user_nodenames);
00389 
00390       xexit (0);
00391     }
00392 
00393   /* If there are arguments remaining, they are the names of menu items
00394      in sequential info files starting from the first one loaded.  That
00395      file name is either "dir", or the contents of user_filename if one
00396      was specified. */
00397   {
00398     const char *errstr;
00399     char *errarg1, *errarg2;
00400 
00401     NODE *new_initial_node = info_follow_menus (initial_node, argv + optind,
00402         &errstr, &errarg1, &errarg2);
00403 
00404     if (new_initial_node && new_initial_node != initial_node)
00405       initial_node = new_initial_node;
00406 
00407     if (print_where_p)
00408       {
00409         if (initial_node->parent)
00410           printf ("%s\n", initial_node->parent);
00411         else if (initial_node->filename
00412             && !is_dir_name (filename_non_directory (initial_node->filename)))
00413           printf ("%s\n", initial_node->filename);
00414         else
00415           xexit (1);
00416         xexit (0);
00417       }
00418 
00419     /* If the user specified that this node should be output, then do that
00420        now.  Otherwise, start the Info session with this node.  Or act
00421        accordingly if the initial node was not found.  */
00422     if (user_output_filename && !goto_invocation_p)
00423       {
00424         if (!errstr)
00425           dump_node_to_file (initial_node, user_output_filename,
00426                              dump_subnodes);
00427         else
00428           info_error ((char *) errstr, errarg1, errarg2);
00429       }
00430     else
00431       {
00432 
00433         if (errstr)
00434           begin_info_session_with_error (initial_node, (char *) errstr,
00435               errarg1, errarg2);
00436         /* If the user specified `--index-search=STRING' or
00437            --show-options, start the info session in the node
00438            corresponding to what they want. */
00439         else if (index_search_p || goto_invocation_p)
00440           {
00441             int status = 0;
00442 
00443             initialize_info_session (initial_node, 0);
00444 
00445             if (goto_invocation_p
00446                 || index_entry_exists (windows, index_search_string))
00447               {
00448                 terminal_prep_terminal ();
00449                 terminal_clear_screen ();
00450                 info_last_executed_command = (VFunction *)NULL;
00451 
00452                 if (index_search_p)
00453                   do_info_index_search (windows, 0, index_search_string);
00454                 else
00455                   {
00456                     /* If they said "info --show-options foo bar baz",
00457                        the last of the arguments is the program whose
00458                        options they want to see.  */
00459                     char **p = argv + optind;
00460                     char *program;
00461 
00462                     if (*p)
00463                       {
00464                         while (p[1])
00465                           p++;
00466                         program = xstrdup (*p);
00467                       }
00468                     else if (user_filename)
00469                     /* If there's no command-line arguments to
00470                       supply the program name, use the Info file
00471                       name (sans extension and leading directories)
00472                       instead.  */
00473                     program = program_name_from_file_name (user_filename);
00474                   else
00475                     program = xstrdup ("");
00476 
00477                     info_intuit_options_node (windows, initial_node, program);
00478                     free (program);
00479                   }
00480 
00481               if (user_output_filename)
00482                 {
00483                   dump_node_to_file (windows->node, user_output_filename,
00484                                    dump_subnodes);
00485                 }
00486               else
00487                 info_read_and_dispatch ();
00488 
00489                 /* On program exit, leave the cursor at the bottom of the
00490                    window, and restore the terminal IO. */
00491                 terminal_goto_xy (0, screenheight - 1);
00492                 terminal_clear_to_eol ();
00493                 fflush (stdout);
00494                 terminal_unprep_terminal ();
00495               }
00496             else
00497               {
00498                 fprintf (stderr, _("no index entries found for `%s'\n"),
00499                          index_search_string);
00500                 status = 2;
00501               }
00502 
00503             close_dribble_file ();
00504             xexit (status);
00505           }
00506         else
00507           begin_info_session (initial_node);
00508       }
00509 
00510     xexit (0);
00511   }
00512 
00513   return 0; /* Avoid bogus warnings.  */
00514 }
00515 
00516 void
00517 add_file_directory_to_path (char *filename)
00518 {
00519   char *directory_name = xstrdup (filename);
00520   char *temp = filename_non_directory (directory_name);
00521 
00522   if (temp != directory_name)
00523     {
00524       if (HAVE_DRIVE (directory_name) && temp == directory_name + 2)
00525        {
00526          /* The directory of "d:foo" is stored as "d:.", to avoid
00527             mixing it with "d:/" when a slash is appended.  */
00528          *temp = '.';
00529          temp += 2;
00530        }
00531       temp[-1] = 0;
00532       info_add_path (directory_name, INFOPATH_PREPEND);
00533     }
00534 
00535   free (directory_name);
00536 }
00537 
00538 
00539 /* Error handling.  */
00540 
00541 /* Non-zero if an error has been signalled. */
00542 int info_error_was_printed = 0;
00543 
00544 /* Non-zero means ring terminal bell on errors. */
00545 int info_error_rings_bell_p = 1;
00546 
00547 /* Print FORMAT with ARG1 and ARG2.  If the window system was initialized,
00548    then the message is printed in the echo area.  Otherwise, a message is
00549    output to stderr. */
00550 void
00551 info_error (char *format, void *arg1, void *arg2)
00552 {
00553   info_error_was_printed = 1;
00554 
00555   if (!info_windows_initialized_p || display_inhibited)
00556     {
00557       fprintf (stderr, "%s: ", program_name);
00558       fprintf (stderr, format, arg1, arg2);
00559       fprintf (stderr, "\n");
00560       fflush (stderr);
00561     }
00562   else
00563     {
00564       if (!echo_area_is_active)
00565         {
00566           if (info_error_rings_bell_p)
00567             terminal_ring_bell ();
00568           window_message_in_echo_area (format, arg1, arg2);
00569         }
00570       else
00571         {
00572           NODE *temp;
00573 
00574           temp = build_message_node (format, arg1, arg2);
00575           if (info_error_rings_bell_p)
00576             terminal_ring_bell ();
00577           inform_in_echo_area (temp->contents);
00578           free (temp->contents);
00579           free (temp);
00580         }
00581     }
00582 }
00583 
00584 
00585 /* Produce a scaled down description of the available options to Info. */
00586 static void
00587 info_short_help (void)
00588 {
00589 #ifdef __MSDOS__
00590   static const char speech_friendly_string[] = N_("\
00591   -b, --speech-friendly        be friendly to speech synthesizers.\n");
00592 #else
00593   static const char speech_friendly_string[] = "";
00594 #endif
00595 
00596 
00597   printf (_("\
00598 Usage: %s [OPTION]... [MENU-ITEM...]\n\
00599 \n\
00600 Read documentation in Info format.\n\
00601 \n\
00602 Options:\n\
00603       --apropos=STRING         look up STRING in all indices of all manuals.\n\
00604   -d, --directory=DIR          add DIR to INFOPATH.\n\
00605       --dribble=FILENAME       remember user keystrokes in FILENAME.\n\
00606   -f, --file=FILENAME          specify Info file to visit.\n\
00607   -h, --help                   display this help and exit.\n\
00608       --index-search=STRING    go to node pointed by index entry STRING.\n\
00609   -n, --node=NODENAME          specify nodes in first visited Info file.\n\
00610   -o, --output=FILENAME        output selected nodes to FILENAME.\n\
00611   -R, --raw-escapes            output \"raw\" ANSI escapes (default).\n\
00612       --no-raw-escapes         output escapes as literal text.\n\
00613       --restore=FILENAME       read initial keystrokes from FILENAME.\n\
00614   -O, --show-options, --usage  go to command-line options node.\n%s\
00615       --subnodes               recursively output menu items.\n\
00616   -w, --where, --location      print physical location of Info file.\n\
00617       --vi-keys                use vi-like and less-like key bindings.\n\
00618       --version                display version information and exit.\n\
00619 \n\
00620 The first non-option argument, if present, is the menu entry to start from;\n\
00621 it is searched for in all `dir' files along INFOPATH.\n\
00622 If it is not present, info merges all `dir' files and shows the result.\n\
00623 Any remaining arguments are treated as the names of menu\n\
00624 items relative to the initial node visited.\n\
00625 \n\
00626 Examples:\n\
00627   info                       show top-level dir menu\n\
00628   info emacs                 start at emacs node from top-level dir\n\
00629   info emacs buffers         start at buffers node within emacs manual\n\
00630   info --show-options emacs  start at node with emacs' command line options\n\
00631   info -f ./foo.info         show file ./foo.info, not searching dir\n\
00632 "),
00633   program_name, speech_friendly_string);
00634 
00635   puts (_("\n\
00636 Email bug reports to bug-texinfo@gnu.org,\n\
00637 general questions and discussion to help-texinfo@gnu.org.\n\
00638 Texinfo home page: http://www.gnu.org/software/texinfo/"));
00639 
00640   xexit (0);
00641 }
00642 
00643 
00644 /* Initialize strings for gettext.  Because gettext doesn't handle N_ or
00645    _ within macro definitions, we put shared messages into variables and
00646    use them that way.  This also has the advantage that there's only one
00647    copy of the strings.  */
00648 
00649 const char *msg_cant_find_node;
00650 const char *msg_cant_file_node;
00651 const char *msg_cant_find_window;
00652 const char *msg_cant_find_point;
00653 const char *msg_cant_kill_last;
00654 const char *msg_no_menu_node;
00655 const char *msg_no_foot_node;
00656 const char *msg_no_xref_node;
00657 const char *msg_no_pointer;
00658 const char *msg_unknown_command;
00659 const char *msg_term_too_dumb;
00660 const char *msg_at_node_bottom;
00661 const char *msg_at_node_top;
00662 const char *msg_one_window;
00663 const char *msg_win_too_small;
00664 const char *msg_cant_make_help;
00665 
00666 static void
00667 init_messages (void)
00668 {
00669   msg_cant_find_node   = _("Cannot find node `%s'.");
00670   msg_cant_file_node   = _("Cannot find node `(%s)%s'.");
00671   msg_cant_find_window = _("Cannot find a window!");
00672   msg_cant_find_point  = _("Point doesn't appear within this window's node!");
00673   msg_cant_kill_last   = _("Cannot delete the last window.");
00674   msg_no_menu_node     = _("No menu in this node.");
00675   msg_no_foot_node     = _("No footnotes in this node.");
00676   msg_no_xref_node     = _("No cross references in this node.");
00677   msg_no_pointer       = _("No `%s' pointer for this node.");
00678   msg_unknown_command  = _("Unknown Info command `%c'; try `?' for help.");
00679   msg_term_too_dumb    = _("Terminal type `%s' is not smart enough to run Info.");
00680   msg_at_node_bottom   = _("You are already at the last page of this node.");
00681   msg_at_node_top      = _("You are already at the first page of this node.");
00682   msg_one_window       = _("Only one window.");
00683   msg_win_too_small    = _("Resulting window would be too small.");
00684   msg_cant_make_help   = _("Not enough room for a help window, please delete a window.");
00685 }