142660Smarkm/* info.c -- Display nodes of Info files in multiple windows. 2146515Sru $Id: info.c,v 1.11 2004/04/11 17:56:45 karl Exp $ 321495Sjmacd 4146515Sru Copyright (C) 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 5146515Sru 2004 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 80146515Sru/* Non-zero means don't remove ANSI escape sequences. */ 81146515Sruint raw_escapes_p = 1; 8293139Sru 83146515Sru/* Non-zero means print the absolute location of the file to be loaded. */ 84146515Srustatic int print_where_p = 0; 85146515Sru 8656160Sru#ifdef __MSDOS__ 8756160Sru/* Non-zero indicates that screen output should be made 'speech-friendly'. 8856160Sru Since on MSDOS the usual behavior is to write directly to the video 8956160Sru memory, speech synthesizer software cannot grab the output. Therefore, 9056160Sru we provide a user option which tells us to avoid direct screen output 9156160Sru and use stdout instead (which loses the color output). */ 9256160Sruint speech_friendly = 0; 9356160Sru#endif 9456160Sru 9521495Sjmacd/* Structure describing the options that Info accepts. We pass this structure 9621495Sjmacd to getopt_long (). If you add or otherwise change this structure, you must 9721495Sjmacd also change the string which follows it. */ 9821495Sjmacd#define APROPOS_OPTION 1 9921495Sjmacd#define DRIBBLE_OPTION 2 10021495Sjmacd#define RESTORE_OPTION 3 10142660Smarkm#define IDXSRCH_OPTION 4 10221495Sjmacdstatic struct option long_options[] = { 10321495Sjmacd { "apropos", 1, 0, APROPOS_OPTION }, 10421495Sjmacd { "directory", 1, 0, 'd' }, 105100513Sru { "dribble", 1, 0, DRIBBLE_OPTION }, 106100513Sru { "file", 1, 0, 'f' }, 107100513Sru { "help", 0, &print_help_p, 1 }, 108100513Sru { "index-search", 1, 0, IDXSRCH_OPTION }, 109146515Sru { "location", 0, &print_where_p, 1 }, 11021495Sjmacd { "node", 1, 0, 'n' }, 11121495Sjmacd { "output", 1, 0, 'o' }, 11293139Sru { "raw-escapes", 0, &raw_escapes_p, 1 }, 113146515Sru { "no-raw-escapes", 0, &raw_escapes_p, 0 }, 114100513Sru { "restore", 1, 0, RESTORE_OPTION }, 11556160Sru { "show-options", 0, 0, 'O' }, 116100513Sru { "subnodes", 0, &dump_subnodes, 1 }, 11756160Sru { "usage", 0, 0, 'O' }, 118100513Sru { "version", 0, &print_version_p, 1 }, 11956160Sru { "vi-keys", 0, &vi_keys_p, 1 }, 120146515Sru { "where", 0, &print_where_p, 1 }, 12156160Sru#ifdef __MSDOS__ 12256160Sru { "speech-friendly", 0, &speech_friendly, 1 }, 12356160Sru#endif 12421495Sjmacd {NULL, 0, NULL, 0} 12521495Sjmacd}; 12621495Sjmacd 12721495Sjmacd/* String describing the shorthand versions of the long options found above. */ 12856160Sru#ifdef __MSDOS__ 129146515Srustatic char *short_options = "d:n:f:ho:ORswb"; 13056160Sru#else 131146515Srustatic char *short_options = "d:n:f:ho:ORws"; 13256160Sru#endif 13321495Sjmacd 13421495Sjmacd/* When non-zero, the Info window system has been initialized. */ 13521495Sjmacdint info_windows_initialized_p = 0; 13621495Sjmacd 13721495Sjmacd/* Some "forward" declarations. */ 138146515Srustatic void info_short_help (void); 139146515Srustatic void init_messages (void); 14021495Sjmacd 14121495Sjmacd 14221495Sjmacd/* **************************************************************** */ 14342660Smarkm/* */ 14442660Smarkm/* Main Entry Point to the Info Program */ 14542660Smarkm/* */ 14621495Sjmacd/* **************************************************************** */ 14721495Sjmacd 14821495Sjmacdint 149146515Srumain (int argc, char **argv) 15021495Sjmacd{ 15142660Smarkm int getopt_long_index; /* Index returned by getopt_long (). */ 15242660Smarkm NODE *initial_node; /* First node loaded by Info. */ 15321495Sjmacd 15442660Smarkm#ifdef HAVE_SETLOCALE 15542660Smarkm /* Set locale via LC_ALL. */ 15642660Smarkm setlocale (LC_ALL, ""); 15742660Smarkm#endif 15842660Smarkm 159146515Sru#ifdef ENABLE_NLS 16042660Smarkm /* Set the text message domain. */ 16142660Smarkm bindtextdomain (PACKAGE, LOCALEDIR); 16242660Smarkm textdomain (PACKAGE); 163146515Sru#endif 16442660Smarkm 16556160Sru init_messages (); 166116525Sru 16721495Sjmacd while (1) 16821495Sjmacd { 16921495Sjmacd int option_character; 17021495Sjmacd 17121495Sjmacd option_character = getopt_long 17242660Smarkm (argc, argv, short_options, long_options, &getopt_long_index); 17321495Sjmacd 174116525Sru /* getopt_long returns EOF when there are no more long options. */ 17521495Sjmacd if (option_character == EOF) 17642660Smarkm break; 17721495Sjmacd 17821495Sjmacd /* If this is a long option, then get the short version of it. */ 17921495Sjmacd if (option_character == 0 && long_options[getopt_long_index].flag == 0) 18042660Smarkm option_character = long_options[getopt_long_index].val; 18121495Sjmacd 18221495Sjmacd /* Case on the option that we have received. */ 18321495Sjmacd switch (option_character) 18442660Smarkm { 18542660Smarkm case 0: 18642660Smarkm break; 18721495Sjmacd 18842660Smarkm /* User wants to add a directory. */ 18942660Smarkm case 'd': 19042660Smarkm info_add_path (optarg, INFOPATH_PREPEND); 19142660Smarkm break; 19221495Sjmacd 19342660Smarkm /* User is specifying a particular node. */ 19442660Smarkm case 'n': 19542660Smarkm add_pointer_to_array (optarg, user_nodenames_index, user_nodenames, 19642660Smarkm user_nodenames_slots, 10, char *); 19742660Smarkm break; 19821495Sjmacd 19942660Smarkm /* User is specifying a particular Info file. */ 20042660Smarkm case 'f': 20142660Smarkm if (user_filename) 20242660Smarkm free (user_filename); 20321495Sjmacd 20442660Smarkm user_filename = xstrdup (optarg); 20542660Smarkm break; 20621495Sjmacd 207116525Sru /* Treat -h like --help. */ 208116525Sru case 'h': 209116525Sru print_help_p = 1; 210116525Sru break; 211116525Sru 21242660Smarkm /* User is specifying the name of a file to output to. */ 21342660Smarkm case 'o': 21442660Smarkm if (user_output_filename) 21542660Smarkm free (user_output_filename); 21642660Smarkm user_output_filename = xstrdup (optarg); 21742660Smarkm break; 21821495Sjmacd 21956160Sru /* User has specified that she wants to find the "Options" 22056160Sru or "Invocation" node for the program. */ 22156160Sru case 'O': 22256160Sru goto_invocation_p = 1; 22356160Sru break; 22456160Sru 22593139Sru /* User has specified that she wants the escape sequences 22693139Sru in man pages to be passed thru unaltered. */ 22793139Sru case 'R': 22893139Sru raw_escapes_p = 1; 22993139Sru break; 23093139Sru 23142660Smarkm /* User is specifying that she wishes to dump the subnodes of 23242660Smarkm the node that she is dumping. */ 23342660Smarkm case 's': 23442660Smarkm dump_subnodes = 1; 23542660Smarkm break; 23621495Sjmacd 237146515Sru /* For compatibility with man, -w is --where. */ 238146515Sru case 'w': 239146515Sru print_where_p = 1; 240146515Sru break; 241146515Sru 24256160Sru#ifdef __MSDOS__ 24393139Sru /* User wants speech-friendly output. */ 24456160Sru case 'b': 24556160Sru speech_friendly = 1; 24656160Sru break; 24756160Sru#endif /* __MSDOS__ */ 24856160Sru 24942660Smarkm /* User has specified a string to search all indices for. */ 25042660Smarkm case APROPOS_OPTION: 25142660Smarkm apropos_p = 1; 25242660Smarkm maybe_free (apropos_search_string); 25342660Smarkm apropos_search_string = xstrdup (optarg); 25442660Smarkm break; 25521495Sjmacd 25642660Smarkm /* User has specified a dribble file to receive keystrokes. */ 25742660Smarkm case DRIBBLE_OPTION: 25842660Smarkm close_dribble_file (); 25942660Smarkm open_dribble_file (optarg); 26042660Smarkm break; 26121495Sjmacd 26242660Smarkm /* User has specified an alternate input stream. */ 26342660Smarkm case RESTORE_OPTION: 26442660Smarkm info_set_input_from_file (optarg); 26542660Smarkm break; 26621495Sjmacd 26742660Smarkm /* User has specified a string to search all indices for. */ 26842660Smarkm case IDXSRCH_OPTION: 26942660Smarkm index_search_p = 1; 27042660Smarkm maybe_free (index_search_string); 27142660Smarkm index_search_string = xstrdup (optarg); 27242660Smarkm break; 27342660Smarkm 27442660Smarkm default: 27556160Sru fprintf (stderr, _("Try --help for more information.\n")); 27656160Sru xexit (1); 27742660Smarkm } 27821495Sjmacd } 27921495Sjmacd 28021495Sjmacd /* If the output device is not a terminal, and no output filename has been 28121495Sjmacd specified, make user_output_filename be "-", so that the info is written 28221495Sjmacd to stdout, and turn on the dumping of subnodes. */ 28321495Sjmacd if ((!isatty (fileno (stdout))) && (user_output_filename == (char *)NULL)) 28421495Sjmacd { 28542660Smarkm user_output_filename = xstrdup ("-"); 28621495Sjmacd dump_subnodes = 1; 28721495Sjmacd } 28821495Sjmacd 28921495Sjmacd /* If the user specified --version, then show the version and exit. */ 29021495Sjmacd if (print_version_p) 29121495Sjmacd { 29256160Sru printf ("%s (GNU %s) %s\n", program_name, PACKAGE, VERSION); 29356160Sru puts (""); 294146515Sru puts ("Copyright (C) 2004 Free Software Foundation, Inc."); 295146515Sru printf (_("There is NO warranty. You may redistribute this software\n\ 29621495Sjmacdunder the terms of the GNU General Public License.\n\ 297146515SruFor more information about these matters, see the files named COPYING.\n")); 29856160Sru xexit (0); 29921495Sjmacd } 30021495Sjmacd 30121495Sjmacd /* If the `--help' option was present, show the help and exit. */ 30221495Sjmacd if (print_help_p) 30321495Sjmacd { 30421495Sjmacd info_short_help (); 30556160Sru xexit (0); 30621495Sjmacd } 30756160Sru 30842660Smarkm /* If the user hasn't specified a path for Info files, default it. 30942660Smarkm Lowest priority is our messy hardwired list in filesys.h. 31042660Smarkm Then comes the user's INFODIR from the Makefile. 31142660Smarkm Highest priority is the environment variable, if set. */ 31221495Sjmacd if (!infopath) 31321495Sjmacd { 31442660Smarkm char *path_from_env = getenv ("INFOPATH"); 31521495Sjmacd 31621495Sjmacd if (path_from_env) 31742660Smarkm { 31842660Smarkm unsigned len = strlen (path_from_env); 31942660Smarkm /* Trailing : on INFOPATH means insert the default path. */ 32056160Sru if (len && path_from_env[len - 1] == PATH_SEP[0]) 32142660Smarkm { 32242660Smarkm path_from_env[len - 1] = 0; 32342660Smarkm info_add_path (DEFAULT_INFOPATH, INFOPATH_PREPEND); 32442660Smarkm } 32542660Smarkm#ifdef INFODIR /* from the Makefile */ 32642660Smarkm info_add_path (INFODIR, INFOPATH_PREPEND); 32742660Smarkm#endif 32842660Smarkm info_add_path (path_from_env, INFOPATH_PREPEND); 32942660Smarkm } 33021495Sjmacd else 33142660Smarkm { 33242660Smarkm info_add_path (DEFAULT_INFOPATH, INFOPATH_PREPEND); 33342660Smarkm#ifdef INFODIR /* from the Makefile */ 334146515Sru info_add_path (INFODIR, INFOPATH_PREPEND); 33542660Smarkm#endif 336146515Sru#ifdef INFODIR2 /* from the Makefile, too */ 337146515Sru# ifdef INFODIR 338146515Sru if (!STREQ (INFODIR, INFODIR2)) 339146515Sru# endif 340146515Sru info_add_path (INFODIR2, INFOPATH_PREPEND); 341146515Sru#endif 34242660Smarkm } 34321495Sjmacd } 34421495Sjmacd 34521495Sjmacd /* If the user specified a particular filename, add the path of that 34621495Sjmacd file to the contents of INFOPATH. */ 34721495Sjmacd if (user_filename) 34893139Sru add_file_directory_to_path (user_filename); 34921495Sjmacd 35021495Sjmacd /* If the user wants to search every known index for a given string, 35121495Sjmacd do that now, and report the results. */ 35221495Sjmacd if (apropos_p) 35321495Sjmacd { 35421495Sjmacd info_apropos (apropos_search_string); 35556160Sru xexit (0); 35621495Sjmacd } 35721495Sjmacd 35821495Sjmacd /* Get the initial Info node. It is either "(dir)Top", or what the user 35921495Sjmacd specifed with values in user_filename and user_nodenames. */ 36042660Smarkm initial_node = info_get_node (user_filename, 36156160Sru user_nodenames ? user_nodenames[0] : 0); 36221495Sjmacd 36321495Sjmacd /* If we couldn't get the initial node, this user is in trouble. */ 36421495Sjmacd if (!initial_node) 36521495Sjmacd { 36621495Sjmacd if (info_recent_file_error) 367146515Sru info_error (info_recent_file_error, NULL, NULL); 36821495Sjmacd else 369146515Sru info_error ((char *) msg_cant_find_node, 370146515Sru user_nodenames ? user_nodenames[0] : "Top", NULL); 37156160Sru xexit (1); 37221495Sjmacd } 37321495Sjmacd 37442660Smarkm /* Special cases for when the user specifies multiple nodes. If we 37542660Smarkm are dumping to an output file, dump all of the nodes specified. 37642660Smarkm Otherwise, attempt to create enough windows to handle the nodes 37742660Smarkm that this user wants displayed. */ 37821495Sjmacd if (user_nodenames_index > 1) 37921495Sjmacd { 38021495Sjmacd free (initial_node); 38121495Sjmacd 382146515Sru if (print_where_p) 383146515Sru printf ("%s\n", user_filename ? user_filename : "unknown?!"); 384146515Sru else if (user_output_filename) 38542660Smarkm dump_nodes_to_file 38642660Smarkm (user_filename, user_nodenames, user_output_filename, dump_subnodes); 38721495Sjmacd else 38842660Smarkm begin_multiple_window_info_session (user_filename, user_nodenames); 38921495Sjmacd 39056160Sru xexit (0); 39121495Sjmacd } 39221495Sjmacd 39321495Sjmacd /* If there are arguments remaining, they are the names of menu items 39421495Sjmacd in sequential info files starting from the first one loaded. That 39521495Sjmacd file name is either "dir", or the contents of user_filename if one 39621495Sjmacd was specified. */ 39756160Sru { 398146515Sru const char *errstr; 399146515Sru char *errarg1, *errarg2; 400146515Sru 40156160Sru NODE *new_initial_node = info_follow_menus (initial_node, argv + optind, 402146515Sru &errstr, &errarg1, &errarg2); 40393139Sru 40456160Sru if (new_initial_node && new_initial_node != initial_node) 40556160Sru initial_node = new_initial_node; 40621495Sjmacd 407146515Sru if (print_where_p) 408146515Sru { 409146515Sru if (initial_node->parent) 410146515Sru printf ("%s\n", initial_node->parent); 411146515Sru else if (initial_node->filename 412146515Sru && !is_dir_name (filename_non_directory (initial_node->filename))) 413146515Sru printf ("%s\n", initial_node->filename); 414146515Sru else 415146515Sru xexit (1); 416146515Sru xexit (0); 417146515Sru } 418146515Sru 41956160Sru /* If the user specified that this node should be output, then do that 42056160Sru now. Otherwise, start the Info session with this node. Or act 42156160Sru accordingly if the initial node was not found. */ 42293139Sru if (user_output_filename && !goto_invocation_p) 42356160Sru { 42456160Sru if (!errstr) 42556160Sru dump_node_to_file (initial_node, user_output_filename, 42656160Sru dump_subnodes); 42756160Sru else 428146515Sru info_error ((char *) errstr, errarg1, errarg2); 42956160Sru } 43056160Sru else 43156160Sru { 43221495Sjmacd 43356160Sru if (errstr) 434146515Sru begin_info_session_with_error (initial_node, (char *) errstr, 435146515Sru errarg1, errarg2); 43656160Sru /* If the user specified `--index-search=STRING' or 43756160Sru --show-options, start the info session in the node 43856160Sru corresponding to what they want. */ 43956160Sru else if (index_search_p || goto_invocation_p) 44056160Sru { 44156160Sru int status = 0; 44221495Sjmacd 44356160Sru initialize_info_session (initial_node, 0); 44421495Sjmacd 44556160Sru if (goto_invocation_p 44656160Sru || index_entry_exists (windows, index_search_string)) 44756160Sru { 44856160Sru terminal_prep_terminal (); 44956160Sru terminal_clear_screen (); 45056160Sru info_last_executed_command = (VFunction *)NULL; 45121495Sjmacd 45256160Sru if (index_search_p) 45356160Sru do_info_index_search (windows, 0, index_search_string); 45456160Sru else 45556160Sru { 45656160Sru /* If they said "info --show-options foo bar baz", 45756160Sru the last of the arguments is the program whose 45856160Sru options they want to see. */ 45956160Sru char **p = argv + optind; 46056160Sru char *program; 46121495Sjmacd 46256160Sru if (*p) 46356160Sru { 46456160Sru while (p[1]) 46556160Sru p++; 46656160Sru program = xstrdup (*p); 46756160Sru } 46856160Sru else if (user_filename) 46956160Sru /* If there's no command-line arguments to 47056160Sru supply the program name, use the Info file 47156160Sru name (sans extension and leading directories) 47256160Sru instead. */ 47356160Sru program = program_name_from_file_name (user_filename); 47456160Sru else 47556160Sru program = xstrdup (""); 47621495Sjmacd 47756160Sru info_intuit_options_node (windows, initial_node, program); 47856160Sru free (program); 47956160Sru } 48021495Sjmacd 48193139Sru if (user_output_filename) 48293139Sru { 48393139Sru dump_node_to_file (windows->node, user_output_filename, 48493139Sru dump_subnodes); 48593139Sru } 48693139Sru else 48793139Sru info_read_and_dispatch (); 48821495Sjmacd 48956160Sru /* On program exit, leave the cursor at the bottom of the 49056160Sru window, and restore the terminal IO. */ 49156160Sru terminal_goto_xy (0, screenheight - 1); 49256160Sru terminal_clear_to_eol (); 49356160Sru fflush (stdout); 49456160Sru terminal_unprep_terminal (); 49556160Sru } 49656160Sru else 49756160Sru { 49856160Sru fprintf (stderr, _("no index entries found for `%s'\n"), 49956160Sru index_search_string); 50056160Sru status = 2; 50156160Sru } 50221495Sjmacd 50356160Sru close_dribble_file (); 50456160Sru xexit (status); 50556160Sru } 50656160Sru else 50756160Sru begin_info_session (initial_node); 50856160Sru } 50921495Sjmacd 51056160Sru xexit (0); 51156160Sru } 512116525Sru 513116525Sru return 0; /* Avoid bogus warnings. */ 51421495Sjmacd} 51521495Sjmacd 51693139Sruvoid 517146515Sruadd_file_directory_to_path (char *filename) 51893139Sru{ 51993139Sru char *directory_name = xstrdup (filename); 52093139Sru char *temp = filename_non_directory (directory_name); 52193139Sru 52293139Sru if (temp != directory_name) 52393139Sru { 52493139Sru if (HAVE_DRIVE (directory_name) && temp == directory_name + 2) 52593139Sru { 52693139Sru /* The directory of "d:foo" is stored as "d:.", to avoid 52793139Sru mixing it with "d:/" when a slash is appended. */ 52893139Sru *temp = '.'; 52993139Sru temp += 2; 53093139Sru } 53193139Sru temp[-1] = 0; 53293139Sru info_add_path (directory_name, INFOPATH_PREPEND); 53393139Sru } 53493139Sru 53593139Sru free (directory_name); 53693139Sru} 53793139Sru 53821495Sjmacd 53942660Smarkm/* Error handling. */ 54021495Sjmacd 54121495Sjmacd/* Non-zero if an error has been signalled. */ 54221495Sjmacdint info_error_was_printed = 0; 54321495Sjmacd 54421495Sjmacd/* Non-zero means ring terminal bell on errors. */ 54521495Sjmacdint info_error_rings_bell_p = 1; 54621495Sjmacd 54721495Sjmacd/* Print FORMAT with ARG1 and ARG2. If the window system was initialized, 54821495Sjmacd then the message is printed in the echo area. Otherwise, a message is 54921495Sjmacd output to stderr. */ 55021495Sjmacdvoid 551146515Sruinfo_error (char *format, void *arg1, void *arg2) 55221495Sjmacd{ 55321495Sjmacd info_error_was_printed = 1; 55421495Sjmacd 55521495Sjmacd if (!info_windows_initialized_p || display_inhibited) 55621495Sjmacd { 55721495Sjmacd fprintf (stderr, "%s: ", program_name); 55821495Sjmacd fprintf (stderr, format, arg1, arg2); 55921495Sjmacd fprintf (stderr, "\n"); 56021495Sjmacd fflush (stderr); 56121495Sjmacd } 56221495Sjmacd else 56321495Sjmacd { 56421495Sjmacd if (!echo_area_is_active) 56542660Smarkm { 56642660Smarkm if (info_error_rings_bell_p) 56742660Smarkm terminal_ring_bell (); 56842660Smarkm window_message_in_echo_area (format, arg1, arg2); 56942660Smarkm } 57021495Sjmacd else 57142660Smarkm { 57242660Smarkm NODE *temp; 57321495Sjmacd 57442660Smarkm temp = build_message_node (format, arg1, arg2); 57542660Smarkm if (info_error_rings_bell_p) 57642660Smarkm terminal_ring_bell (); 57742660Smarkm inform_in_echo_area (temp->contents); 57842660Smarkm free (temp->contents); 57942660Smarkm free (temp); 58042660Smarkm } 58121495Sjmacd } 58221495Sjmacd} 58321495Sjmacd 58456160Sru 58521495Sjmacd/* Produce a scaled down description of the available options to Info. */ 58621495Sjmacdstatic void 587146515Sruinfo_short_help (void) 58821495Sjmacd{ 58993139Sru#ifdef __MSDOS__ 59093139Sru static const char speech_friendly_string[] = N_("\ 591100513Sru -b, --speech-friendly be friendly to speech synthesizers.\n"); 59293139Sru#else 59393139Sru static const char speech_friendly_string[] = ""; 59493139Sru#endif 59593139Sru 596116525Sru 59742660Smarkm printf (_("\ 59856160SruUsage: %s [OPTION]... [MENU-ITEM...]\n\ 59921495Sjmacd\n\ 60042660SmarkmRead documentation in Info format.\n\ 60121495Sjmacd\n\ 60242660SmarkmOptions:\n\ 603100513Sru --apropos=STRING look up STRING in all indices of all manuals.\n\ 604100513Sru -d, --directory=DIR add DIR to INFOPATH.\n\ 605100513Sru --dribble=FILENAME remember user keystrokes in FILENAME.\n\ 606100513Sru -f, --file=FILENAME specify Info file to visit.\n\ 607100513Sru -h, --help display this help and exit.\n\ 608100513Sru --index-search=STRING go to node pointed by index entry STRING.\n\ 609100513Sru -n, --node=NODENAME specify nodes in first visited Info file.\n\ 610100513Sru -o, --output=FILENAME output selected nodes to FILENAME.\n\ 611146515Sru -R, --raw-escapes output \"raw\" ANSI escapes (default).\n\ 612146515Sru --no-raw-escapes output escapes as literal text.\n\ 613100513Sru --restore=FILENAME read initial keystrokes from FILENAME.\n\ 614100513Sru -O, --show-options, --usage go to command-line options node.\n%s\ 615100513Sru --subnodes recursively output menu items.\n\ 616146515Sru -w, --where, --location print physical location of Info file.\n\ 617100513Sru --vi-keys use vi-like and less-like key bindings.\n\ 618100513Sru --version display version information and exit.\n\ 61921495Sjmacd\n\ 62056160SruThe first non-option argument, if present, is the menu entry to start from;\n\ 62156160Sruit is searched for in all `dir' files along INFOPATH.\n\ 62256160SruIf it is not present, info merges all `dir' files and shows the result.\n\ 62342660SmarkmAny remaining arguments are treated as the names of menu\n\ 62456160Sruitems relative to the initial node visited.\n\ 62542660Smarkm\n\ 62656160SruExamples:\n\ 62756160Sru info show top-level dir menu\n\ 62856160Sru info emacs start at emacs node from top-level dir\n\ 62956160Sru info emacs buffers start at buffers node within emacs manual\n\ 63056160Sru info --show-options emacs start at node with emacs' command line options\n\ 63156160Sru info -f ./foo.info show file ./foo.info, not searching dir\n\ 63256160Sru"), 63393139Sru program_name, speech_friendly_string); 63421495Sjmacd 635100513Sru puts (_("\n\ 636100513SruEmail bug reports to bug-texinfo@gnu.org,\n\ 637100513Srugeneral questions and discussion to help-texinfo@gnu.org.\n\ 638100513SruTexinfo home page: http://www.gnu.org/software/texinfo/")); 639100513Sru 64056160Sru xexit (0); 64121495Sjmacd} 64256160Sru 64356160Sru 64456160Sru/* Initialize strings for gettext. Because gettext doesn't handle N_ or 64556160Sru _ within macro definitions, we put shared messages into variables and 64656160Sru use them that way. This also has the advantage that there's only one 64756160Sru copy of the strings. */ 64856160Sru 649116525Sruconst char *msg_cant_find_node; 650116525Sruconst char *msg_cant_file_node; 651116525Sruconst char *msg_cant_find_window; 652116525Sruconst char *msg_cant_find_point; 653116525Sruconst char *msg_cant_kill_last; 654116525Sruconst char *msg_no_menu_node; 655116525Sruconst char *msg_no_foot_node; 656116525Sruconst char *msg_no_xref_node; 657116525Sruconst char *msg_no_pointer; 658116525Sruconst char *msg_unknown_command; 659116525Sruconst char *msg_term_too_dumb; 660116525Sruconst char *msg_at_node_bottom; 661116525Sruconst char *msg_at_node_top; 662116525Sruconst char *msg_one_window; 663116525Sruconst char *msg_win_too_small; 664116525Sruconst char *msg_cant_make_help; 66556160Sru 66656160Srustatic void 667146515Sruinit_messages (void) 66856160Sru{ 66956160Sru msg_cant_find_node = _("Cannot find node `%s'."); 67056160Sru msg_cant_file_node = _("Cannot find node `(%s)%s'."); 67156160Sru msg_cant_find_window = _("Cannot find a window!"); 67256160Sru msg_cant_find_point = _("Point doesn't appear within this window's node!"); 67356160Sru msg_cant_kill_last = _("Cannot delete the last window."); 67456160Sru msg_no_menu_node = _("No menu in this node."); 67556160Sru msg_no_foot_node = _("No footnotes in this node."); 67656160Sru msg_no_xref_node = _("No cross references in this node."); 67756160Sru msg_no_pointer = _("No `%s' pointer for this node."); 67856160Sru msg_unknown_command = _("Unknown Info command `%c'; try `?' for help."); 67956160Sru msg_term_too_dumb = _("Terminal type `%s' is not smart enough to run Info."); 68056160Sru msg_at_node_bottom = _("You are already at the last page of this node."); 68156160Sru msg_at_node_top = _("You are already at the first page of this node."); 68256160Sru msg_one_window = _("Only one window."); 68356160Sru msg_win_too_small = _("Resulting window would be too small."); 68456160Sru msg_cant_make_help = _("Not enough room for a help window, please delete a window."); 68556160Sru} 686