# HG changeset patch # User jwe # Date 751240672 0 # Node ID 49ab724d0a326ba6737715fe9fcf1025462ef80b # Parent a500c60e8f2351daee62bf1474978acc228d2df5 [project @ 1993-10-21 21:56:38 by jwe] diff --git a/Makeconf.in b/Makeconf.in --- a/Makeconf.in +++ b/Makeconf.in @@ -18,6 +18,7 @@ YFLAGS = -dv INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ RANLIB = @RANLIB@ @@ -26,6 +27,8 @@ DEFAULT_PAGER = @DEFAULT_PAGER@ +DEFAULT_INFO_FILE = $(infodir)/octave.info + # Fortran to C translator and associated flags. F2C = @F2C@ diff --git a/octMakefile.in b/octMakefile.in --- a/octMakefile.in +++ b/octMakefile.in @@ -22,7 +22,7 @@ DISTDIRS = bsd-math dld # Subdirectories to run make in for the primary targets. -SUBDIRS = libcruft liboctave @DLD_DIR@ readline src doc scripts +SUBDIRS = libcruft liboctave @DLD_DIR@ info readline src doc scripts # Subdirectories to run `make dist' in DISTSUBDIRS = $(SUBDIRS) test @@ -53,6 +53,10 @@ cd dld ; $(MAKE) all .PHONY: dld +info: + cd info ; $(MAKE) all +.PHONY: info + readline: cd readline ; $(MAKE) all .PHONY: readline diff --git a/src/builtins.cc b/src/builtins.cc --- a/src/builtins.cc +++ b/src/builtins.cc @@ -846,20 +846,21 @@ bind_protected_variable ("stderr", tmp); make_eternal ("stderr"); +// If using 1.0 / 0.0 doesn't work, you might also try using a very +// large constant like 1.0e100000. + #if defined (HAVE_ISINF) || defined (HAVE_FINITE) #ifdef linux - tmp = new tree_constant (HUGE_VAL); + double tmp_inf = HUGE_VAL; #else - tmp = new tree_constant (1.0/0.0); + double tmp_inf = 1.0 / 0.0; #endif + + tmp = new tree_constant (tmp_inf); bind_protected_variable ("Inf", tmp); make_eternal ("Inf"); -#ifdef linux - tmp = new tree_constant (HUGE_VAL); -#else - tmp = new tree_constant (1.0/0.0); -#endif + tmp = new tree_constant (tmp_inf); bind_protected_variable ("inf", tmp); make_eternal ("inf"); @@ -877,20 +878,21 @@ make_eternal ("inf"); #endif +// If tmp_inf / tmp_inf fails to produce a NaN, you might also try +// something like 0.0 / 0.0. + #if defined (HAVE_ISNAN) #ifdef linux - tmp = new tree_constant (NAN); + double tmp_nan = NAN; #else - tmp = new tree_constant (0.0/0.0); + double tmp_nan = tmp_inf / tmp_inf; #endif + + tmp = new tree_constant (tmp_nan); bind_protected_variable ("NaN", tmp); make_eternal ("NaN"); -#ifdef linux - tmp = new tree_constant (NAN); -#else - tmp = new tree_constant (0.0/0.0); -#endif + tmp = new tree_constant (tmp_nan); bind_protected_variable ("nan", tmp); make_eternal ("nan"); #endif diff --git a/src/error.cc b/src/error.cc --- a/src/error.cc +++ b/src/error.cc @@ -30,6 +30,7 @@ #include #include "error.h" +#include "pager.h" // Current error state. int error_state; @@ -78,6 +79,8 @@ if (! error_state) error_state = 1; + flush_output_to_pager (); + va_list args; va_start (args, fmt); verror ("error", fmt, args); @@ -87,6 +90,8 @@ void volatile panic (const char *fmt, ...) { + flush_output_to_pager (); + va_list args; va_start (args, fmt); verror ("panic", fmt, args); diff --git a/src/lex.l b/src/lex.l --- a/src/lex.l +++ b/src/lex.l @@ -1315,20 +1315,7 @@ { BEGIN TEXT_FCN; - if (strcmp (tok, "clear") == 0) - { - symbol_record *sr = global_sym_tab->lookup ("clear", 1, 0); - - assert (sr != (symbol_record *) NULL); - - yylval.tok_val = new token (sr, input_line_number, - current_input_column); - - token_stack.push (yylval.tok_val); - - return CLEAR; - } - else if (strcmp (tok, "help") == 0) + if (strcmp (tok, "help") == 0) BEGIN HELP_FCN; else if (strcmp (tok, "set") == 0) doing_set = 1; diff --git a/src/parse.y b/src/parse.y --- a/src/parse.y +++ b/src/parse.y @@ -168,7 +168,7 @@ %token LEFTDIV EMUL EDIV ELEFTDIV QUOTE TRANSPOSE %token PLUS_PLUS MINUS_MINUS POW EPOW %token NUM IMAG_NUM -%token NAME SCREW CLEAR +%token NAME SCREW %token END %token PLOT %token TEXT STYLE @@ -213,8 +213,8 @@ %left UNARY PLUS_PLUS MINUS_MINUS EXPR_NOT %right POW EPOW -// There are 20 shift/reduce conflicts, ok? -%expect 20 +// There are 19 shift/reduce conflicts, ok? +%expect 19 // Where to start. %start input @@ -792,31 +792,6 @@ word_list_cmd : identifier word_list { $$ = new tree_word_list_command ($1, $2); } - | CLEAR - { - if (defining_func) - { - yyerror ("parse error"); - error ("clear: invalid within function body"); - ABORT_PARSE; - } - tree_identifier *tmp = new tree_identifier - ($1->sym_rec (), $1->line (), $1->column ()); - $$ = new tree_word_list_command (tmp, - (tree_word_list *) NULL); - } - | CLEAR word_list - { - if (defining_func) - { - yyerror ("parse error"); - error ("clear: invalid within function body"); - ABORT_PARSE; - } - tree_identifier *tmp = new tree_identifier - ($1->sym_rec (), $1->line (), $1->column ()); - $$ = new tree_word_list_command (tmp, $2); - } ; word_list : word_list1 diff --git a/src/symtab.cc b/src/symtab.cc --- a/src/symtab.cc +++ b/src/symtab.cc @@ -463,24 +463,6 @@ } void -symbol_record::undefine (void) -{ - if (var != (symbol_def *) NULL) - { - if (--var->count <= 0) - delete var; - var = (symbol_def *) NULL; - } - - if (fcn != (symbol_def *) NULL) - { - if (--fcn->count <= 0) - delete fcn; - fcn = (symbol_def *) NULL; - } -} - -void symbol_record::mark_as_formal_parameter (void) { formal_param = 1; @@ -579,27 +561,12 @@ { for (int i = 0; i < HASH_TABLE_SIZE; i++) { - symbol_record *prev = &table[i]; - symbol_record *curr = prev->next (); - - while (curr != (symbol_record *) NULL) - { - curr->clear_all (); + symbol_record *ptr = table[i].next (); -// This record might have been read only. If so, we shouldn't delete -// it from the table. - if (curr->is_defined ()) - { - prev = curr; - curr = curr->next (); - } - else - { - prev->next_elem = curr->next (); - symbol_record *tmp = curr; - curr = curr->next (); - delete tmp; - } + while (ptr != (symbol_record *) NULL) + { + ptr->clear_all (); + ptr = ptr->next (); } } } @@ -618,14 +585,6 @@ { curr->clear_visible (); - if (! curr->is_defined ()) - { - prev->next_elem = curr->next (); - symbol_record *tmp = curr; - curr = curr->next (); - delete tmp; - } - return 1; } prev = curr; @@ -635,21 +594,6 @@ return 0; } -void -symbol_table::undefine (void) -{ - for (int i = 0; i < HASH_TABLE_SIZE; i++) - { - symbol_record *ptr = table[i].next (); - - while (ptr != (symbol_record *) NULL) - { - ptr->undefine (); - ptr = ptr->next (); - } - } -} - // Ugh. void diff --git a/src/symtab.h b/src/symtab.h --- a/src/symtab.h +++ b/src/symtab.h @@ -156,7 +156,6 @@ void clear_visible (void); void clear_all (void); - void undefine (void); void mark_as_formal_parameter (void); int is_formal_parameter (void) const; @@ -196,7 +195,6 @@ void clear (void); int clear (const char *nm); - void undefine (void); void bind_globals (void); diff --git a/src/t-builtins.cc b/src/t-builtins.cc --- a/src/t-builtins.cc +++ b/src/t-builtins.cc @@ -50,6 +50,7 @@ #include #include #include +#include #include #include "procstream.h" @@ -60,12 +61,14 @@ #include "input.h" #include "pager.h" #include "utils.h" +#include "sighandlers.h" #include "builtins.h" #include "t-builtins.h" #include "octave.h" #include "octave-hist.h" #include "user-prefs.h" #include "pr-output.h" +#include "defaults.h" #include "tree.h" #include "help.h" @@ -76,6 +79,19 @@ char *tilde_expand (char *s); /* From readline's tilde.c */ } +extern "C" +{ +#include "info.h" +#include "dribble.h" +#include "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 (); +} + extern int symbol_out_of_date (symbol_record *s); // Is this a parametric plot? Makes a difference for 3D plotting. @@ -231,7 +247,8 @@ if (argc == 1) { curr_sym_tab->clear (); - global_sym_tab->clear (); + if (curr_sym_tab == top_level_sym_tab) + global_sym_tab->clear (); } else { @@ -263,13 +280,16 @@ } } - for (i = 0; i < g_count; i++) + if (curr_sym_tab == top_level_sym_tab) { - String nm (g_names[i]); - if (nm.matches (rx) - && ! in_list (g_names[i], locals_cleared)) + for (i = 0; i < g_count; i++) { - global_sym_tab->clear (g_names[i]); + String nm (g_names[i]); + if (nm.matches (rx) + && ! in_list (g_names[i], locals_cleared)) + { + global_sym_tab->clear (g_names[i]); + } } } } @@ -336,6 +356,143 @@ return retval; } +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 != (char **) NULL && 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 != (char **) NULL) + { + while (*ptr != (char *) NULL) + { + int count; + char **names = get_m_file_names (count, *ptr, 0); + output_buf << "\n*** M-files in " + << make_absolute (*ptr, the_current_working_directory) + << ":\n\n"; + if (names != (char **) NULL && count > 0) + list_in_columns (output_buf, names); + delete [] names; + ptr++; + } + } + + output_buf << ends; + maybe_page_output (output_buf); +} + +static int +try_info (const char *string) +{ + int status = 0; + + char *directory_name = strsave (DEFAULT_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 (DEFAULT_INFO_FILE, (char *)NULL); + + if (! initial_node) + { + warning ("can't find info file!\n"); + return status; + } + + initialize_info_session (initial_node, 0); + + if (index_entry_exists (windows, string)) + { + terminal_clear_screen (); + + terminal_prep_terminal (); + + display_update_display (windows); + + info_last_executed_command = (VFunction *)NULL; + + 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; +} + +static int +help_from_list (ostrstream& output_buf, const help_list *list, + const char *string) +{ + char *name; + while ((name = list->name) != (char *) NULL) + { + if (strcmp (name, string) == 0) + { + output_buf << "\n" << list->help << "\n"; + return 1; + } + list++; + } + return 0; +} + /* * Print cryptic yet witty messages. */ @@ -344,106 +501,39 @@ { tree_constant retval; - ostrstream output_buf; if (argc == 1) { - char **symbols; - int count = 0; - - symbols = names (operator_help (), count); - output_buf << "\n*** operators:\n\n"; - if (symbols != (char **) NULL && count > 0) - list_in_columns (output_buf, symbols); - delete [] symbols; - - symbols = names (keyword_help (), count); - output_buf << "\n*** reserved words:\n\n"; - if (symbols != (char **) NULL && count > 0) - list_in_columns (output_buf, symbols); - delete [] symbols; - - symbols = names (builtin_text_functions_help (), count); - output_buf - << "\n*** text functions (these names are also reserved):\n\n"; - if (symbols != (char **) NULL && count > 0) - list_in_columns (output_buf, symbols); - delete [] symbols; - - symbols = names (builtin_mapper_functions_help (), count); - output_buf << "\n*** mapper functions:\n\n"; - if (symbols != (char **) NULL && count > 0) - list_in_columns (output_buf, symbols); - delete [] symbols; - - symbols = names (builtin_general_functions_help (), count); - output_buf << "\n*** general functions:\n\n"; - if (symbols != (char **) NULL && count > 0) - list_in_columns (output_buf, symbols); - delete [] symbols; - - symbols = names (builtin_variables_help (), count); - output_buf << "\n*** builtin variables:\n\n"; - if (symbols != (char **) NULL && count > 0) - list_in_columns (output_buf, symbols); - delete [] symbols; - -// 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 != (char **) NULL) - { - while (*ptr != (char *) NULL) - { - int count; - char **names = get_m_file_names (count, *ptr, 0); - output_buf << "\n*** M-files in " - << make_absolute (*ptr, the_current_working_directory) - << ":\n\n"; - if (names != (char **) NULL && count > 0) - list_in_columns (output_buf, names); - delete [] names; - ptr++; - } - } + simple_help (); } else { + ostrstream output_buf; + char *m_file_name = (char *) NULL; symbol_record *sym_rec; help_list *op_help_list = operator_help (); help_list *kw_help_list = keyword_help (); + for (int i = 1; i < argc; i++) { if (argv[i] == (char *) NULL || argv[i][0] == '\0') continue; - int j = 0; - char *name; - while ((name = op_help_list[j].name) != (char *) NULL) - { - if (strcmp (name, argv[i]) == 0) - { - output_buf << "\n" << op_help_list[j].help << "\n"; - goto next; - } - j++; - } + volatile sig_handler *old_sigint_handler = signal (SIGINT, SIG_IGN); + + int help_found = try_info (argv[i]); + + signal (SIGINT, old_sigint_handler); - j = 0; - while ((name = kw_help_list[j].name) != (char *) NULL) - { - if (strcmp (name, argv[i]) == 0) - { - output_buf << "\n" << kw_help_list[j].help << "\n"; - goto next; - } - j++; - } + if (help_found) + continue; + + + if (help_from_list (output_buf, op_help_list, argv[i])) + continue; + + if (help_from_list (output_buf, kw_help_list, argv[i])) + continue; sym_rec = curr_sym_tab->lookup (argv[i], 0, 0); if (sym_rec != (symbol_record *) NULL) @@ -452,7 +542,7 @@ if (h != (char *) NULL && *h != '\0') { output_buf << "\n" << h << "\n"; - goto next; + continue; } } @@ -464,7 +554,7 @@ if (h != (char *) NULL && *h != '\0') { output_buf << "\n" << h << "\n"; - goto next; + continue; } } @@ -484,22 +574,19 @@ if (h != (char *) NULL && *h != '\0') { output_buf << "\n" << h << "\n"; - goto next; + continue; } } } delete [] m_file_name; output_buf << "Sorry, `" << argv[i] << "' is not documented\n"; + } - next: - continue; - } + output_buf << ends; + maybe_page_output (output_buf); } - output_buf << ends; - maybe_page_output (output_buf); - return retval; } @@ -579,7 +666,6 @@ * BUGS: * * -- This function is not terribly robust. - * -- Symbols are only inserted into the current symbol table. */ tree_constant builtin_load (int argc, char **argv) diff --git a/src/utils.cc b/src/utils.cc --- a/src/utils.cc +++ b/src/utils.cc @@ -244,7 +244,7 @@ // Set the modes to the way we want them. s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL); - s.c_oflag |= (OPOST|ONLCR|TAB3); + s.c_oflag |= (OPOST|ONLCR); s.c_oflag &= ~(OCRNL|ONOCR|ONLRET); s.c_cc[VMIN] = 1; s.c_cc[VTIME] = 0; @@ -277,7 +277,7 @@ // Set the modes to the way we want them. s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL); - s.c_oflag |= (OPOST|ONLCR|TAB3); + s.c_oflag |= (OPOST|ONLCR); s.c_oflag &= ~(OCRNL|ONOCR|ONLRET); s.c_cc[VMIN] = 1; s.c_cc[VTIME] = 0; @@ -310,7 +310,7 @@ // Set the modes to the way we want them. s.sg_flags |= CBREAK; - s.sg_flags &= ~(ECHO|XTABS); + s.sg_flags &= ~(ECHO); } else {