Mercurial > hg > octave-nkf
diff src/help.cc @ 529:7ea224e713cd
[project @ 1994-07-20 18:54:27 by jwe]
author | jwe |
---|---|
date | Wed, 20 Jul 1994 19:19:08 +0000 |
parents | 4cb0c5015dc3 |
children | 682393bf54f7 |
line wrap: on
line diff
--- a/src/help.cc +++ b/src/help.cc @@ -25,11 +25,42 @@ #include "config.h" #endif +#include <signal.h> +#include <stdlib.h> #include <iostream.h> +#include <strstream.h> -#include "builtins.h" +#include "tree.h" +#include "sighandlers.h" +#include "user-prefs.h" +#include "tree-expr.h" +#include "variables.h" +#include "oct-obj.h" +#include "symtab.h" +#include "octave.h" +#include "dirfns.h" +#include "pager.h" +#include "error.h" #include "utils.h" #include "help.h" +#include "defun.h" + +extern "C" +{ +#include "info/info.h" +#include "info/dribble.h" +#include "info/terminal.h" + +extern int initialize_info_session (); +extern int index_entry_exists (); +extern int do_info_index_search (); +extern void finish_info_session (); +extern char *replace_in_documentation (); + +// XXX FIXME XXX +#undef __FUNCTION_DEF +#include <readline/tilde.h> +} static help_list operators[] = { @@ -159,7 +190,7 @@ { "~=", "Logical not equals operator. See also `<>' and `!='.\n", }, - { (char *) NULL, (char *) NULL, }, + { 0, 0, }, }; static help_list keywords[] = @@ -215,7 +246,7 @@ { "while", "Begin a while loop.\n", }, - { (char *) NULL, (char *) NULL, }, + { 0, 0, }, }; /* @@ -226,26 +257,26 @@ { count = 0; help_list *ptr = lst; - while (ptr->name != (char *) NULL) + while (ptr->name) { count++; ptr++; } if (count == 0) - return (char **) NULL; + return 0; char **name_list = new char * [count+1]; ptr = lst; int i = 0; - while (ptr->name != (char *) NULL) + while (ptr->name) { name_list[i++] = strsave (ptr->name); ptr++; } - name_list[i] = (char *) NULL; + name_list[i] = 0; return name_list; } @@ -261,6 +292,267 @@ return keywords; } +static void +help_syms_list (ostrstream& output_buf, help_list *list, + const char *desc) +{ + int count = 0; + char **symbols = names (list, count); + output_buf << "\n*** " << desc << ":\n\n"; + if (symbols && count > 0) + list_in_columns (output_buf, symbols); + delete [] symbols; +} + +static void +simple_help (void) +{ + ostrstream output_buf; + + help_syms_list (output_buf, operator_help (), "operators"); + + help_syms_list (output_buf, keyword_help (), "reserved words"); + + help_syms_list (output_buf, builtin_text_functions_help (), + "text functions (these names are also reserved)"); + + help_syms_list (output_buf, builtin_mapper_functions_help (), + "mapper functions"); + + help_syms_list (output_buf, builtin_general_functions_help (), + "general functions"); + + help_syms_list (output_buf, builtin_variables_help (), + "builtin variables"); + +// Also need to list variables and currently compiled functions from +// the symbol table, if there are any. + +// Also need to search octave_path for script files. + + char **path = pathstring_to_vector (user_pref.loadpath); + + char **ptr = path; + if (ptr) + { + while (*ptr) + { + int count; + char **names = get_fcn_file_names (count, *ptr, 0); + output_buf << "\n*** function files in " + << make_absolute (*ptr, the_current_working_directory) + << ":\n\n"; + if (names && count > 0) + list_in_columns (output_buf, names); + delete [] names; + ptr++; + } + } + + additional_help_message (output_buf); + output_buf << ends; + maybe_page_output (output_buf); +} + +static int +try_info (const char *string, int force = 0) +{ + int status = 0; + + char *directory_name = strsave (user_pref.info_file); + char *temp = filename_non_directory (directory_name); + + if (temp != directory_name) + { + *temp = 0; + info_add_path (directory_name, INFOPATH_PREPEND); + } + + delete [] directory_name; + + NODE *initial_node = info_get_node (user_pref.info_file, 0); + + if (! initial_node) + { + warning ("can't find info file!\n"); + status = -1; + } + else + { + status = initialize_info_session (initial_node, 0); + + if (status == 0 && (force || index_entry_exists (windows, string))) + { + terminal_clear_screen (); + + terminal_prep_terminal (); + + display_update_display (windows); + + info_last_executed_command = 0; + + if (! force) + do_info_index_search (windows, 0, string); + + char *format = replace_in_documentation + ("Type \"\\[quit]\" to quit, \"\\[get-help-window]\" for help."); + + window_message_in_echo_area (format); + + info_read_and_dispatch (); + + terminal_goto_xy (0, screenheight - 1); + + terminal_clear_to_eol (); + + terminal_unprep_terminal (); + + status = 1; + } + + finish_info_session (initial_node, 0); + } + + return status; +} + +DEFUN_TEXT ("help", Fhelp, Shelp, -1, 1, + "help [-i] [topic ...]\n\ +\n\ +print cryptic yet witty messages") +{ + Octave_object retval; + + DEFINE_ARGV("help"); + + if (argc == 1) + { + simple_help (); + } + else + { + if (argv[1] && strcmp (argv[1], "-i") == 0) + { + argc--; + argv++; + + if (argc == 1) + { + volatile sig_handler *old_sigint_handler; + old_sigint_handler = signal (SIGINT, SIG_IGN); + + try_info (0, 1); + + signal (SIGINT, old_sigint_handler); + } + else + { + while (--argc > 0) + { + argv++; + + if (! *argv || ! **argv) + continue; + + volatile sig_handler *old_sigint_handler; + old_sigint_handler = signal (SIGINT, SIG_IGN); + + if (! try_info (*argv)) + { + message ("help", + "sorry, `%s' is not indexed in the manual", + *argv); + sleep (2); + } + + signal (SIGINT, old_sigint_handler); + } + } + } + else + { + ostrstream output_buf; + + char *fcn_file_name = 0; + symbol_record *sym_rec; + help_list *op_help_list = operator_help (); + help_list *kw_help_list = keyword_help (); + + while (--argc > 0) + { + argv++; + + if (! *argv || ! **argv) + continue; + + if (help_from_list (output_buf, op_help_list, *argv, 0)) + continue; + + if (help_from_list (output_buf, kw_help_list, *argv, 0)) + continue; + + sym_rec = curr_sym_tab->lookup (*argv, 0, 0); + if (sym_rec) + { + char *h = sym_rec->help (); + if (h && *h) + { + output_buf << "\n*** " << *argv << ":\n\n" + << h << "\n"; + continue; + } + } + + sym_rec = global_sym_tab->lookup (*argv, 0, 0); + if (sym_rec && ! symbol_out_of_date (sym_rec)) + { + char *h = sym_rec->help (); + if (h && *h) + { + output_buf << "\n*** " << *argv << ":\n\n" + << h << "\n"; + continue; + } + } + +// Try harder to find function files that might not be defined yet, or +// that appear to be out of date. Don\'t execute commands from the +// file if it turns out to be a script file. + + fcn_file_name = fcn_file_in_path (*argv); + if (fcn_file_name) + { + sym_rec = global_sym_tab->lookup (*argv, 1, 0); + if (sym_rec) + { + tree_identifier tmp (sym_rec); + tmp.parse_fcn_file (0); + char *h = sym_rec->help (); + if (h && *h) + { + output_buf << "\n*** " << *argv << ":\n\n" + << h << "\n"; + continue; + } + } + } + delete [] fcn_file_name; + + output_buf << "\nhelp: sorry, `" << *argv + << "' is not documented\n"; + } + + additional_help_message (output_buf); + output_buf << ends; + maybe_page_output (output_buf); + } + } + + DELETE_ARGV; + + return retval; +} + /* ;;; Local Variables: *** ;;; mode: C++ ***