Mercurial > hg > octave-shane
changeset 2926:66ef74ee5d9f
[project @ 1997-05-05 03:20:52 by jwe]
line wrap: on
line diff
--- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,36 @@ +Sun May 4 22:17:08 1997 John W. Eaton <jwe@bevo.che.wisc.edu> + + * statdefs.h: Only include sys/types.h if HAVE_SYS_STAT_H is defined. + + * mach-info.h, mach-info.cc: Add missing const qualifiers. + (instance_ok ()): New function. + + * glob-match.h, glob-match.cc: Rename from oct-glob.h, oct-glob.cc. + + * cmd-hist.h, cmd-hist.cc: Make it work without GNU readline. + + * lo-utils.h, lo-utils.cc (strsave, octave_putenv): Move here from + src/utils.h and src/utils.cc. + (octave_fgets): New function, extracted from src/input.cc. + + * cmd-edit.h, cmd-edit.cc: New files. Provide wrapper class for + GNU readline, and allow Octave to work without GNU readline. + + * lo-sysdep.h, lo-sysdep.cc: New files for miscellaneous + system-dependent functions. + + * oct-env.h, oct-env.cc: New files for process environment stuff. + + * file-stat.h, file-stat.cc: New files. Extract file_stat class + from file-ops.h and file-ops.cc and move here. + + * file-ops.h, file-ops.cc: Wrap functions in struct. Move + tilde_expand functions here from src/dirfns.cc. + +Fri May 2 19:50:12 1997 John W. Eaton <jwe@bevo.che.wisc.edu> + + * pathlen.h: New file, from ../src. + Tue Apr 29 04:39:01 1997 John W. Eaton <jwe@bevo.che.wisc.edu> * Array2-idx.h (Array2<T>::maybe_delete_elements): Prevent
--- a/liboctave/Makefile.in +++ b/liboctave/Makefile.in @@ -43,11 +43,12 @@ INCLUDES := Bounds.h CollocWt.h DAE.h DAEFunc.h DASSL.h FEGrid.h FSQP.h \ LinConst.h LP.h LPsolve.h LSODE.h NLConst.h NLEqn.h NLFunc.h \ NLP.h NPSOL.h ODE.h ODEFunc.h Objective.h QP.h QPSOL.h Quad.h \ - Range.h base-de.h base-min.h byte-swap.h cmd-hist.h data-conv.h \ - dir-ops.h file-ops.h getopt.h idx-vector.h \ - lo-ieee.h lo-mappers.h lo-utils.h mach-info.h oct-alloc.h \ - oct-cmplx.h oct-glob.h oct-math.h oct-term.h pathsearch.h \ - prog-args.h statdefs.h str-vec.h sun-utils.h sysdir.h \ + Range.h base-de.h base-min.h byte-swap.h cmd-edit.h cmd-hist.h \ + data-conv.h dir-ops.h file-ops.h file-stat.h getopt.h \ + glob-match.h idx-vector.h lo-ieee.h lo-mappers.h lo-sysdep.h \ + lo-utils.h mach-info.h oct-alloc.h oct-cmplx.h oct-env.h \ + oct-math.h pathsearch.h prog-args.h statdefs.h str-vec.h \ + sun-utils.h sysdir.h \ $(MATRIX_INC) \ $(MX_OP_INC) @@ -75,12 +76,13 @@ SOURCES := Bounds.cc CollocWt.cc DAE.cc DASSL.cc FEGrid.cc FSQP.cc \ LinConst.cc LPsolve.cc LSODE.cc NLEqn.cc NPSOL.cc QPSOL.cc \ - Quad.cc Range.cc acosh.c asinh.c atanh.c cmd-hist.cc \ - data-conv.cc dir-ops.cc erf.c erfc.c f2c-main.c file-ops.cc \ - filemode.c gamma.c getopt.c getopt1.c idx-vector.cc lgamma.c \ - lo-ieee.cc lo-mappers.cc lo-utils.cc mach-info.cc mkdir.c \ - oct-alloc.cc oct-glob.cc oct-term.cc pathsearch.cc \ - prog-args.cc rename.c rmdir.c str-vec.cc tempname.c tempnam.c \ + Quad.cc Range.cc acosh.c asinh.c atanh.c cmd-edit.cc \ + cmd-hist.cc data-conv.cc dir-ops.cc erf.c erfc.c f2c-main.c \ + file-ops.cc file-stat.cc filemode.c gamma.c getopt.c getopt1.c \ + glob-match.cc idx-vector.cc lgamma.c lo-ieee.cc lo-mappers.cc \ + lo-sysdep.cc lo-utils.cc mach-info.cc mkdir.c oct-alloc.cc \ + oct-env.cc pathsearch.cc prog-args.cc rename.c rmdir.c \ + str-vec.cc tempname.c tempnam.c \ $(TEMPLATE_SRC) \ $(TI_SRC) \ $(MATRIX_SRC) \
new file mode 100644 --- /dev/null +++ b/liboctave/cmd-edit.cc @@ -0,0 +1,850 @@ +/* + +Copyright (C) 1996, 1997 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <cstring> +#include <ctime> + +#include <string> + +#ifdef HAVE_UNISTD_H +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#include <unistd.h> +#endif + +#include "cmd-edit.h" +#include "cmd-hist.h" +#include "lo-error.h" +#include "lo-utils.h" +#include "oct-env.h" + +command_editor *command_editor::instance = 0; + +#if defined (USE_READLINE) + +#include <cstdio> +#include <cstdlib> + +#include <readline/readline.h> + +// It would be nice if readline.h declared these, I think. + +extern "C" void rl_deprep_terminal (void); + +extern int rl_blink_matching_paren; + +extern int screenheight; + +extern int screenwidth; + +class +gnu_readline : public command_editor +{ +public: + + typedef command_editor::fcn fcn; + + gnu_readline (void); + + ~gnu_readline (void) { } + + void do_set_name (const string& n); + + string do_readline (const string& prompt); + + void do_set_input_stream (FILE *f); + + FILE *do_get_input_stream (void); + + void do_set_output_stream (FILE *f); + + FILE *do_get_output_stream (void); + + int do_terminal_rows (void); + + int do_terminal_cols (void); + + void do_clear_screen (void); + + string newline_chars (void); + + void do_restore_terminal_state (void); + + void do_blink_matching_paren (bool flag); + + void do_set_paren_string_delimiters (const string& s); + + void do_set_completion_append_character (char c); + + void do_set_attempted_completion_function (fcn f); + + void do_insert_text (const string& text); + + void do_newline (void); + + void do_clear_undo_list (void); + + void do_set_startup_hook (fcn f); + + void do_restore_startup_hook (void); + + static void operate_and_get_next (int, int); + +private: + + fcn previous_startup_hook; + + fcn attempted_completion_function; +}; + +gnu_readline::gnu_readline () + : command_editor (), previous_startup_hook (0), + attempted_completion_function (0) +{ + rl_initialize (); + + do_blink_matching_paren (true); + + // Bind operate-and-get-next. + + rl_add_defun ("operate-and-get-next", + gnu_readline::operate_and_get_next, CTRL ('O')); + + // And the history search functions. + + rl_add_defun ("history-search-backward", + rl_history_search_backward, META ('p')); + + rl_add_defun ("history-search-forward", + rl_history_search_forward, META ('n')); +} + +void +gnu_readline::do_set_name (const string& n) +{ + static char *nm = 0; + + delete [] nm; + + nm = strsave (n.c_str ()); + + rl_readline_name = nm; + + // Since we've already called rl_initialize, we need to re-read the + // init file to take advantage of the conditional parsing feature + // based on rl_readline_name; + + rl_re_read_init_file (); +} + +string +gnu_readline::do_readline (const string& prompt) +{ + string retval; + + char *line = ::readline (prompt.c_str ()); + + if (line) + { + retval = line; + + free (line); + } + + return retval; +} + +void +gnu_readline::do_set_input_stream (FILE *f) +{ + rl_instream = f; +} + +FILE * +gnu_readline::do_get_input_stream (void) +{ + return rl_instream; +} + +void +gnu_readline::do_set_output_stream (FILE *f) +{ + rl_outstream = f; +} + +FILE * +gnu_readline::do_get_output_stream (void) +{ + return rl_outstream; +} + +// GNU readline handles SIGWINCH, so these values have a good chance +// of being correct even if the window changes size (they may be +// wrong if, for example, the luser changes the window size while the +// pager is running, and the signal is handled by the pager instead of +// us. + +int +gnu_readline::do_terminal_rows (void) +{ + return screenheight > 0 ? screenheight : 24; +} + +int +gnu_readline::do_terminal_cols (void) +{ + return screenwidth > 0 ? screenwidth : 80; +} + +void +gnu_readline::do_clear_screen (void) +{ + rl_clear_screen (); +} + +string +gnu_readline::newline_chars (void) +{ + return "\r\n"; +} + +void +gnu_readline::do_restore_terminal_state (void) +{ + rl_deprep_terminal (); +} + +void +gnu_readline::do_blink_matching_paren (bool flag) +{ + rl_blink_matching_paren = flag ? 1 : 0; +} + +void +gnu_readline::do_set_paren_string_delimiters (const string& s) +{ + static char *ss = 0; + + delete [] ss; + + ss = strsave (s.c_str ()); + + rl_paren_string_delimiters = ss; +} + +void +gnu_readline::do_set_completion_append_character (char c) +{ + rl_completion_append_character = c; +} + +void +gnu_readline::do_set_attempted_completion_function (fcn f) +{ + attempted_completion_function = f; +} + +void +gnu_readline::do_insert_text (const string& text) +{ + rl_insert_text (text.c_str ()); +} + +void +gnu_readline::do_newline (void) +{ + rl_newline (); +} + +void +gnu_readline::do_clear_undo_list () +{ + if (rl_undo_list) + { + free_undo_list (); + + rl_undo_list = 0; + } +} + +void +gnu_readline::do_set_startup_hook (fcn f) +{ + previous_startup_hook = rl_startup_hook; + + rl_startup_hook = f; +} + +void +gnu_readline::do_restore_startup_hook (void) +{ + rl_startup_hook = previous_startup_hook; +} + +void +gnu_readline::operate_and_get_next (int /* count */, int /* c */) +{ + // Accept the current line. + + command_editor::newline (); + + // Find the current line, and find the next line to use. + + int x_where = command_history::where (); + + int x_length = command_history::length (); + + if ((command_history::is_stifled () + && (x_length >= command_history::max_input_history ())) + || (x_where >= x_length - 1)) + command_history::set_mark (x_where); + else + command_history::set_mark (x_where + 1); + + command_editor::set_startup_hook (command_history::goto_mark); +} + +#endif + +class +default_command_editor : public command_editor +{ +public: + + default_command_editor (void) + : command_editor (), input_stream (stdin), output_stream (stdout) { } + + ~default_command_editor (void) { } + + string do_readline (const string& prompt); + + void do_set_input_stream (FILE *f); + + FILE *do_get_input_stream (void); + + void do_set_output_stream (FILE *f); + + FILE *do_get_output_stream (void); + + void do_insert_text (const string&); + + void do_newline (void); + +private: + + FILE *input_stream; + + FILE *output_stream; +}; + +string +default_command_editor::do_readline (const string& prompt) +{ + fprintf (output_stream, prompt.c_str ()); + fflush (output_stream); + + return octave_fgets (input_stream); +} + +void +default_command_editor::do_set_input_stream (FILE *f) +{ + input_stream = f; +} + +FILE * +default_command_editor::do_get_input_stream (void) +{ + return input_stream; +} + +void +default_command_editor::do_set_output_stream (FILE *f) +{ + output_stream = f; +} + +FILE * +default_command_editor::do_get_output_stream (void) +{ + return output_stream; +} + +void +default_command_editor::do_insert_text (const string&) +{ + // XXX FIXME XXX +} + +void +default_command_editor::do_newline (void) +{ + // XXX FIXME XXX +} + +bool +command_editor::instance_ok (void) +{ + bool retval = true; + + if (! instance) + make_command_editor (); + + if (! instance) + { + (*current_liboctave_error_handler) + ("unable to create command history object!"); + + retval = false; + } + + return retval; +} + +void +command_editor::make_command_editor (void) +{ +#if defined (USE_READLINE) + instance = new gnu_readline (); +#else + instance = new default_command_editor (); +#endif +} + +void +command_editor::set_name (const string& n) +{ + if (instance_ok ()) + instance->do_set_name (n); +} + +string +command_editor::readline (const string& prompt) +{ + return (instance_ok ()) + ? instance->do_readline (prompt) : string (); +} + +void +command_editor::set_input_stream (FILE *f) +{ + if (instance_ok ()) + instance->do_set_input_stream (f); +} + +FILE * +command_editor::get_input_stream (void) +{ + return (instance_ok ()) + ? instance->do_get_input_stream () : 0; +} + +void +command_editor::set_output_stream (FILE *f) +{ + if (instance_ok ()) + instance->do_set_output_stream (f); +} + +FILE * +command_editor::get_output_stream (void) +{ + return (instance_ok ()) + ? instance->do_get_output_stream () : 0; +} + +int +command_editor::terminal_rows (void) +{ + return (instance_ok ()) + ? instance->do_terminal_rows () : -1; +} + +int +command_editor::terminal_cols (void) +{ + return (instance_ok ()) + ? instance->do_terminal_cols () : -1; +} + +void +command_editor::clear_screen (void) +{ + if (instance_ok ()) + instance->do_clear_screen (); +} + +string +command_editor::decode_prompt_string (const string& s) +{ + return (instance_ok ()) + ? instance->do_decode_prompt_string (s) : string (); +} + +int +command_editor::current_command_number (void) +{ + return (instance_ok ()) + ? instance->command_number : 0; +} + +void +command_editor::reset_current_command_number (int n) +{ + if (instance_ok ()) + instance->command_number = n; +} + +void +command_editor::restore_terminal_state (void) +{ + if (instance_ok ()) + instance->do_restore_terminal_state (); +} + +void +command_editor::blink_matching_paren (bool flag) +{ + if (instance_ok ()) + instance->do_blink_matching_paren (flag); +} + +void +command_editor::set_paren_string_delimiters (const string& s) +{ + if (instance_ok ()) + instance->do_set_paren_string_delimiters (s); +} + +void +command_editor::set_completion_append_character (char c) +{ + if (instance_ok ()) + instance->do_set_completion_append_character (c); +} + +void +command_editor::set_attempted_completion_function (fcn f) +{ + if (instance_ok ()) + instance->do_set_attempted_completion_function (f); +} + +void +command_editor::insert_text (const string& text) +{ + if (instance_ok ()) + instance->do_insert_text (text); +} + +void +command_editor::newline (void) +{ + if (instance_ok ()) + instance->do_newline (); +} + +void +command_editor::clear_undo_list (void) +{ + if (instance_ok ()) + instance->do_clear_undo_list (); +} + +void +command_editor::set_startup_hook (fcn f) +{ + if (instance_ok ()) + instance->do_set_startup_hook (f); +} + +void +command_editor::restore_startup_hook (void) +{ + if (instance_ok ()) + instance->do_restore_startup_hook (); +} + +// Return a string which will be printed as a prompt. The string may +// contain special characters which are decoded as follows: +// +// \t the time +// \d the date +// \n CRLF +// \s the name of the shell (program) +// \w the current working directory +// \W the last element of PWD +// \u your username +// \h the hostname +// \# the command number of this command +// \! the history number of this command +// \$ a $ or a # if you are root +// \<octal> character code in octal +// \\ a backslash + +string +command_editor::do_decode_prompt_string (const string& s) +{ + string result; + string temp; + size_t i = 0; + size_t slen = s.length (); + int c; + + while (i < slen) + { + c = s[i]; + + i++; + + if (c == '\\') + { + c = s[i]; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + // Maybe convert an octal number. + { + int n = read_octal (s.substr (i, 3)); + + temp = "\\"; + + if (n != -1) + { + i += 3; + temp[0] = n; + } + + c = 0; + goto add_string; + } + + case 't': + case 'd': + // Make the current time/date into a string. + { + time_t now = time (0); + + temp = ctime (&now); + + if (c == 't') + { + temp = temp.substr (11); + temp.resize (8); + } + else + temp.resize (10); + + goto add_string; + } + + case 'n': + { + temp = newline_chars (); + + goto add_string; + } + + case 's': + { + temp = octave_env::get_program_name (); + temp = octave_env::base_pathname (temp); + + goto add_string; + } + + case 'w': + case 'W': + { + temp = octave_env::getcwd (); + + if (c == 'W') + { + size_t pos = temp.rfind ('/'); + + if (pos != NPOS && pos != 0) + temp = temp.substr (pos + 1); + } + else + temp = octave_env::polite_directory_format (temp); + + goto add_string; + } + + case 'u': + { + temp = octave_env::get_user_name (); + + goto add_string; + } + + case 'H': + { + temp = octave_env::get_host_name (); + + goto add_string; + } + + case 'h': + { + temp = octave_env::get_host_name (); + + size_t pos = temp.find ('.'); + + if (pos != NPOS) + temp.resize (pos); + + goto add_string; + } + + case '#': + { + char number_buffer[128]; + sprintf (number_buffer, "%d", command_number); + temp = number_buffer; + + goto add_string; + } + + case '!': + { + char number_buffer[128]; + int num = command_history::current_number (); + if (num > 0) + sprintf (number_buffer, "%d", num); + else + strcpy (number_buffer, "!"); + temp = number_buffer; + + goto add_string; + } + + case '$': + { + temp = (::geteuid () == 0 ? "#" : "$"); + + goto add_string; + } + +#if defined (USE_READLINE) + case '[': + case ']': + { + temp.resize (2); + + temp[0] = '\001'; + temp[1] = ((c == '[') + ? RL_PROMPT_START_IGNORE + : RL_PROMPT_END_IGNORE); + + goto add_string; + } +#endif + + case '\\': + { + temp = "\\"; + + goto add_string; + } + + default: + { + temp = "\\ "; + temp[1] = c; + + goto add_string; + } + + add_string: + { + if (c) + i++; + + result.append (temp); + + break; + } + } + } + else + result += c; + } + + return result; +} + +// Return the octal number parsed from STRING, or -1 to indicate that +// the string contained a bad number. + +int +command_editor::read_octal (const string& s) +{ + int result = 0; + int digits = 0; + + size_t i = 0; + size_t slen = s.length (); + + while (i < slen && s[i] >= '0' && s[i] < '8') + { + digits++; + result = (result * 8) + s[i] - '0'; + i++; + } + + if (! digits || result > 0777 || i < slen) + result = -1; + + return result; +} + +void +command_editor::error (int err_num) +{ + (*current_liboctave_error_handler) ("%s", strerror (err_num)); +} + +void +command_editor::error (const string& s) +{ + (*current_liboctave_error_handler) ("%s", s.c_str ()); +} + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/
new file mode 100644 --- /dev/null +++ b/liboctave/cmd-edit.h @@ -0,0 +1,167 @@ +/* + +Copyright (C) 1996, 1997 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#if !defined (octave_cmd_edit_h) +#define octave_cmd_edit_h 1 + +#include <cstdio> + +#include <string> + +class +command_editor +{ +protected: + + command_editor (void) + : command_number (0) { } + +public: + + typedef int (*fcn) (...); + + virtual ~command_editor (void) { } + + static void set_name (const string& n); + + static string readline (const string& prompt); + + static void set_input_stream (FILE *f); + + static FILE *get_input_stream (void); + + static void set_output_stream (FILE *f); + + static FILE *get_output_stream (void); + + static int terminal_rows (void); + + static int terminal_cols (void); + + static void clear_screen (void); + + static string decode_prompt_string (const string& s); + + static void restore_terminal_state (void); + + static void blink_matching_paren (bool flag); + + static void set_paren_string_delimiters (const string& s); + + static void set_completion_append_character (char c); + + static void set_attempted_completion_function (fcn f); + + static void insert_text (const string& text); + + static void newline (void); + + static void clear_undo_list (void); + + static void set_startup_hook (fcn f); + + static void restore_startup_hook (void); + + static int current_command_number (void); + + static void reset_current_command_number (int n); + +private: + + // No copying! + + command_editor (const command_editor&); + + command_editor& operator = (const command_editor&); + + static bool instance_ok (void); + + static void make_command_editor (void); + + // The real thing. + static command_editor *instance; + +protected: + + // To use something other than the GNU readline library, derive a new + // class from command_editor, overload these functions as + // necessary, and make instance point to the new class. + + virtual void do_set_name (const string&) { } + + virtual string do_readline (const string&) = 0; + + virtual void do_set_input_stream (FILE *) = 0; + + virtual FILE *do_get_input_stream (void) = 0; + + virtual void do_set_output_stream (FILE *) = 0; + + virtual FILE *do_get_output_stream (void) = 0; + + virtual int do_terminal_rows (void) { return 24; } + + virtual int do_terminal_cols (void) { return 80; } + + virtual void do_clear_screen (void) { } + + virtual string do_decode_prompt_string (const string&); + + virtual string newline_chars (void) { return "\n"; } + + virtual void do_restore_terminal_state (void) { } + + virtual void do_blink_matching_paren (bool) { } + + virtual void do_set_paren_string_delimiters (const string&) { } + + virtual void do_set_completion_append_character (char) { } + + virtual void do_set_attempted_completion_function (fcn) { } + + virtual void do_insert_text (const string&) = 0; + + virtual void do_newline (void) = 0; + + virtual void do_clear_undo_list (void) { } + + virtual void do_set_startup_hook (fcn) { } + + virtual void do_restore_startup_hook (void) { } + + int read_octal (const string& s); + + void error (int); + + void error (const string&); + + // The current command number. + int command_number; +}; + +#endif + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/
--- a/liboctave/cmd-hist.cc +++ b/liboctave/cmd-hist.cc @@ -26,6 +26,19 @@ #include <cstring> +#include <string> + +#include "cmd-edit.h" +#include "cmd-hist.h" +#include "lo-error.h" +#include "str-vec.h" + +command_history *command_history::instance = 0; + +#if defined (USE_READLINE) + +#include <cstdlib> + #include <strstream.h> #ifdef HAVE_FCNTL_H @@ -41,95 +54,82 @@ #include <readline/history.h> -#include "file-ops.h" -#include "lo-error.h" -#include "cmd-hist.h" +#include "file-stat.h" -bool command_history::initialized = false; - -command_history::command_history (const string& f, int n) +class +gnu_history : public command_history { - if (initialized) - error ("only one history object can be active at once"); - else - { - ignoring_additions = false; +public: + + gnu_history (void) + : command_history (), mark (0) { } + + ~gnu_history (void) { } + + void do_add (const string&); + + void do_remove (int); - lines_in_file = 0; - lines_this_session = 0; + int do_where (void); + + int do_length (void); + + int do_max_input_history (void); + + int do_base (void); + + int do_current_number (void); + + void do_stifle (int); - xsize = -1; + int do_unstifle (void); + + int do_is_stifled (void); + + void do_set_mark (int); - if (! f.empty ()) - { - xfile = f; + void do_goto_mark (void); + + void do_read (const string&, bool); - ::read_history (f.c_str ()); + void do_read_range (const string&, int, int, bool); - lines_in_file = where (); + void do_write (const string&); - ::using_history (); - } + void do_append (const string&); + + void do_truncate_file (const string&, int); + + string_vector do_list (int, bool); + + string do_get_entry (int); - if (n > 0) - xsize = n; + void do_replace_entry (int, const string&); + + void do_clean_up_and_save (const string&, int); - initialized = true; - } -} +private: + + int mark; +}; void -command_history::set_file (const string& f) -{ - xfile = f; -} - -string -command_history::file (void) -{ - return xfile; -} - -void -command_history::set_size (int n) -{ - xsize = n; -} - -int -command_history::size (void) +gnu_history::do_add (const string& s) { - return xsize; -} - -void -command_history::ignore_entries (bool flag) -{ - ignoring_additions = flag; -} - -bool -command_history::ignoring_entries (void) -{ - return ignoring_additions; -} - -void -command_history::add (const string& s) -{ - if (! ignoring_entries ()) + if (! do_ignoring_entries ()) { if (s.empty () || (s.length () == 1 && (s[0] == '\r' || s[0] == '\n'))) return; ::add_history (s.c_str ()); + lines_this_session++; } } void -command_history::remove (int n) +gnu_history::do_remove (int n) { HIST_ENTRY *discard = ::remove_history (n); @@ -143,49 +143,87 @@ } int -command_history::where (void) +gnu_history::do_where (void) { return ::where_history (); } int -command_history::base (void) +gnu_history::do_length (void) +{ + return ::history_length; +} + +int +gnu_history::do_max_input_history (void) +{ + return ::max_input_history; +} + +int +gnu_history::do_base (void) { return ::history_base; } int -command_history::current_number (void) +gnu_history::do_current_number (void) { - return (xsize > 0) ? base () + where () : -1; + return (xsize > 0) ? do_base () + do_where () : -1; } void -command_history::stifle (int n) +gnu_history::do_stifle (int n) { ::stifle_history (n); } int -command_history::unstifle (void) +gnu_history::do_unstifle (void) { return ::unstifle_history (); } int -command_history::is_stifled (void) +gnu_history::do_is_stifled (void) { return ::history_is_stifled (); } void -command_history::read (bool must_exist) +gnu_history::do_set_mark (int n) { - read (xfile, must_exist); + mark = n; } void -command_history::read (const string& f, bool must_exist) +gnu_history::do_goto_mark (void) +{ + HIST_ENTRY *h; + + if (mark) + { + if (history_set_pos (mark)) + { + h = ::current_history (); + + if (h) + { + command_editor::insert_text (h->line); + + command_editor::clear_undo_list (); + } + } + } + + mark = 0; + + // XXX FIXME XXX -- for operate_and_get_next. + command_editor::restore_startup_hook (); +} + +void +gnu_history::do_read (const string& f, bool must_exist) { if (! f.empty ()) { @@ -195,24 +233,18 @@ error (status); else { - lines_in_file = where (); + lines_in_file = do_where (); ::using_history (); } } else - error ("command_history::read: missing file name"); + error ("gnu_history::read: missing file name"); } void -command_history::read_range (int from, int to, bool must_exist) -{ - read_range (xfile, from, to, must_exist); -} - -void -command_history::read_range (const string& f, int from, int to, - bool must_exist) +gnu_history::do_read_range (const string& f, int from, int to, + bool must_exist) { if (from < 0) from = lines_in_file; @@ -225,17 +257,17 @@ error (status); else { - lines_in_file = where (); + lines_in_file = do_where (); ::using_history (); } } else - error ("command_history::read_range: missing file name"); + error ("gnu_history::read_range: missing file name"); } void -command_history::write (const string& f_arg) +gnu_history::do_write (const string& f_arg) { string f = f_arg; @@ -250,15 +282,15 @@ error (status); } else - error ("command_history::write: missing file name"); + error ("gnu_history::write: missing file name"); } void -command_history::append (const string& f_arg) +gnu_history::do_append (const string& f_arg) { if (lines_this_session) { - if (lines_this_session < where ()) + if (lines_this_session < do_where ()) { // Create file if it doesn't already exist. @@ -289,13 +321,13 @@ lines_this_session = 0; } else - error ("comman_history::append: missing file name"); + error ("gnu_history::append: missing file name"); } } } void -command_history::truncate_file (const string& f_arg, int n) +gnu_history::do_truncate_file (const string& f_arg, int n) { string f = f_arg; @@ -305,11 +337,11 @@ if (! f.empty ()) ::history_truncate_file (f.c_str (), n); else - error ("command_history::truncate_file: missing file name"); + error ("gnu_history::truncate_file: missing file name"); } string_vector -command_history::list (int limit, int number_lines) +gnu_history::do_list (int limit, bool number_lines) { string_vector retval; @@ -333,7 +365,7 @@ ostrstream output_buf; if (number_lines) - output_buf.form ("%5d%c", i + ::history_base, + output_buf.form ("%5d%c", i + do_base (), hlist[i]->data ? '*' : ' '); output_buf << hlist[i]->line << ends; @@ -351,11 +383,11 @@ } string -command_history::get_entry (int n) +gnu_history::do_get_entry (int n) { string retval; - HIST_ENTRY *entry = ::history_get (::history_base + n); + HIST_ENTRY *entry = ::history_get (do_base () + n); if (entry && entry->line) retval = entry->line; @@ -364,7 +396,7 @@ } void -command_history::replace_entry (int which, const string& line) +gnu_history::do_replace_entry (int which, const string& line) { HIST_ENTRY *discard = ::replace_history_entry (which, line.c_str (), 0); @@ -378,7 +410,7 @@ } void -command_history::clean_up_and_save (const string& f_arg, int n) +gnu_history::do_clean_up_and_save (const string& f_arg, int n) { string f = f_arg; @@ -392,9 +424,448 @@ stifle (n); - ::write_history (f.c_str ()); + do_write (f.c_str ()); } else + error ("gnu_history::clean_up_and_save: missing file name"); +} + +#endif + +bool +command_history::instance_ok (void) +{ + bool retval = true; + + if (! instance) + make_command_history (); + + if (! instance) + { + (*current_liboctave_error_handler) + ("unable to create command history object!"); + + retval = false; + } + + return retval; +} + +void +command_history::make_command_history (void) +{ +#if defined (USE_READLINE) + instance = new gnu_history (); +#else + instance = new command_history (); +#endif +} + +void +command_history::set_file (const string& f) +{ + if (instance_ok ()) + instance->do_set_file (f); +} + +string +command_history::file (void) +{ + return (instance_ok ()) + ? instance->do_file () : string (); +} + +void +command_history::set_size (int n) +{ + if (instance_ok ()) + instance->do_set_size (n); +} + +int +command_history::size (void) +{ + return (instance_ok ()) + ? instance->do_size () : 0; +} + +void +command_history::ignore_entries (bool flag) +{ + if (instance_ok ()) + instance->do_ignore_entries (flag); +} + +bool +command_history::ignoring_entries (void) +{ + return (instance_ok ()) + ? instance->do_ignoring_entries () : false; +} + +void +command_history::add (const string& s) +{ + if (instance_ok ()) + instance->do_add (s); +} + +void +command_history::remove (int n) +{ + if (instance_ok ()) + instance->do_remove (n); +} + +int +command_history::where (void) +{ + return (instance_ok ()) + ? instance->do_where () : 0; +} + +int +command_history::length (void) +{ + return (instance_ok ()) + ? instance->do_length () : 0; +} + +int +command_history::max_input_history (void) +{ + return (instance_ok ()) + ? instance->do_max_input_history () : 0; +} + +int +command_history::base (void) +{ + return (instance_ok ()) + ? instance->do_base () : 0; +} + +int +command_history::current_number (void) +{ + return (instance_ok ()) + ? instance->do_current_number () : 0; +} + +void +command_history::stifle (int n) +{ + if (instance_ok ()) + instance->do_stifle (n); +} + +int +command_history::unstifle (void) +{ + return (instance_ok ()) + ? instance->do_unstifle () : 0; +} + +int +command_history::is_stifled (void) +{ + return (instance_ok ()) + ? instance->do_is_stifled () : 0; +} + +void +command_history::set_mark (int n) +{ + if (instance_ok ()) + instance->do_set_mark (n); +} + +int +command_history::goto_mark (...) +{ + if (instance_ok ()) + instance->do_goto_mark (); + + return 0; +} + +void +command_history::read (bool must_exist) +{ + if (instance_ok ()) + instance->do_read (must_exist); +} + +void +command_history::read (const string& f, bool must_exist) +{ + if (instance_ok ()) + instance->do_read (f, must_exist); +} + +void +command_history::read_range (int from, int to, bool must_exist) +{ + if (instance_ok ()) + instance->do_read_range (from, to, must_exist); +} + +void +command_history::read_range (const string& f, int from, int to, + bool must_exist) +{ + if (instance_ok ()) + instance->do_read_range (f, from, to, must_exist); +} + +void +command_history::write (const string& f) +{ + if (instance_ok ()) + instance->do_write (f); +} + +void +command_history::append (const string& f) +{ + if (instance_ok ()) + instance->do_append (f); +} + +void +command_history::truncate_file (const string& f, int n) +{ + if (instance_ok ()) + instance->do_truncate_file (f, n); +} + +string_vector +command_history::list (int limit, bool number_lines) +{ + return (instance_ok ()) + ? instance->do_list (limit, number_lines) : string_vector (); +} + +string +command_history::get_entry (int n) +{ + return (instance_ok ()) + ? instance->do_get_entry (n) : string (); +} + +void +command_history::replace_entry (int which, const string& line) +{ + if (instance_ok ()) + instance->do_replace_entry (which, line); +} + +void +command_history::clean_up_and_save (const string& f, int n) +{ + if (instance_ok ()) + instance->do_clean_up_and_save (f, n); +} + +void +command_history::do_set_file (const string& f) +{ + xfile = f; +} + +string +command_history::do_file (void) +{ + return xfile; +} + +void +command_history::do_set_size (int n) +{ + xsize = n; +} + +int +command_history::do_size (void) +{ + return xsize; +} + +void +command_history::do_ignore_entries (bool flag) +{ + ignoring_additions = flag; +} + +bool +command_history::do_ignoring_entries (void) +{ + return ignoring_additions; +} + +void +command_history::do_add (const string&) +{ +} + +void +command_history::do_remove (int) +{ +} + +int +command_history::do_where (void) +{ + return 0; +} + +int +command_history::do_length (void) +{ + return 0; +} + +int +command_history::do_max_input_history (void) +{ + return 0; +} + +int +command_history::do_base (void) +{ + return 0; +} + +int +command_history::do_current_number (void) +{ + return (xsize > 0) ? do_base () + do_where () : -1; +} + +void +command_history::do_stifle (int) +{ +} + +int +command_history::do_unstifle (void) +{ + return -1; +} + +int +command_history::do_is_stifled (void) +{ + return 0; +} + +void +command_history::do_set_mark (int) +{ +} + +void +command_history::do_goto_mark (void) +{ +} + +void +command_history::do_read (bool must_exist) +{ + do_read (xfile, must_exist); +} + +void +command_history::do_read (const string& f, bool) +{ + if (f.empty ()) + error ("command_history::read: missing file name"); +} + +void +command_history::do_read_range (int from, int to, bool must_exist) +{ + do_read_range (xfile, from, to, must_exist); +} + +void +command_history::do_read_range (const string& f, int, int, bool) +{ + if (f.empty ()) + error ("command_history::read_range: missing file name"); +} + +void +command_history::do_write (const string& f_arg) +{ + string f = f_arg; + + if (f.empty ()) + f = xfile; + + if (f.empty ()) + error ("command_history::write: missing file name"); +} + +void +command_history::do_append (const string& f_arg) +{ + if (lines_this_session) + { + if (lines_this_session < do_where ()) + { + // Create file if it doesn't already exist. + + string f = f_arg; + + if (f.empty ()) + f = xfile; + + if (f.empty ()) + error ("command_history::append: missing file name"); + } + } +} + +void +command_history::do_truncate_file (const string& f_arg, int) +{ + string f = f_arg; + + if (f.empty ()) + f = xfile; + + if (f.empty ()) + error ("command_history::truncate_file: missing file name"); +} + +string_vector +command_history::do_list (int, bool) +{ + return string_vector (); +} + +string +command_history::do_get_entry (int) +{ + return string (); +} + +void +command_history::do_replace_entry (int, const string&) +{ +} + +void +command_history::do_clean_up_and_save (const string& f_arg, int) +{ + string f = f_arg; + + if (f.empty ()) + f = xfile; + + if (f.empty ()) error ("command_history::clean_up_and_save: missing file name"); }
--- a/liboctave/cmd-hist.h +++ b/liboctave/cmd-hist.h @@ -30,67 +30,160 @@ class command_history { +protected: + + command_history (void) + : ignoring_additions (false), lines_in_file (0), + lines_this_session (0), xfile (), xsize (-1) { } + public: - command_history (const string& = string (), int = -1); + virtual ~command_history (void) { } + + static void set_file (const string&); - ~command_history (void) { initialized = false; } + static string file (void); - void set_file (const string&); + static void set_size (int); - string file (void); + static int size (void); + + static void ignore_entries (bool = true); - void set_size (int); + static bool ignoring_entries (void); - int size (void); + static void add (const string&); - void ignore_entries (bool = true); + static void remove (int); + + static int where (void); - bool ignoring_entries (void); + static int length (void); - void add (const string&); + static int max_input_history (void); - void remove (int); + static int base (void); - int where (void); + static int current_number (void); - int base (void); + static void stifle (int); - int current_number (void); + static int unstifle (void); - void stifle (int); + static int is_stifled (void); - int unstifle (void); + static void set_mark (int n); - int is_stifled (void); + // Gag. This declaration has to match the Function typedef in + // readline.h. - void read (bool = true); + static int goto_mark (...); + + static void read (bool = true); - void read (const string&, bool = true); + static void read (const string&, bool = true); - void read_range (int = -1, int = -1, bool = true); + static void read_range (int = -1, int = -1, bool = true); - void read_range (const string&, int = -1, int = -1, - bool = true); + static void read_range (const string&, int = -1, int = -1, + bool = true); - void write (const string& = string ()); + static void write (const string& = string ()); - void append (const string& = string ()); + static void append (const string& = string ()); - void truncate_file (const string& = string (), int = -1); + static void truncate_file (const string& = string (), int = -1); - string_vector list (int = -1, int = 0); + static string_vector list (int = -1, bool = false); - string get_entry (int); + static string get_entry (int); - void replace_entry (int, const string&); + static void replace_entry (int, const string&); - void clean_up_and_save (const string& = string (), int = -1); + static void clean_up_and_save (const string& = string (), int = -1); private: - // We can only have one history object in any given program. - static bool initialized; + // No copying! + + command_history (const command_history&); + + command_history& operator = (const command_history&); + + static bool instance_ok (void); + + static void make_command_history (void); + + // The real thing. + static command_history *instance; + +protected: + + // To use something other than the GNU history library, derive a new + // class from command_history, overload these functions as + // necessary, and make instance point to the new class. + + virtual void do_set_file (const string&); + + virtual string do_file (void); + + virtual void do_set_size (int); + + virtual int do_size (void); + + virtual void do_ignore_entries (bool); + + virtual bool do_ignoring_entries (void); + + virtual void do_add (const string&); + + virtual void do_remove (int); + + virtual int do_where (void); + + virtual int do_length (void); + + virtual int do_max_input_history (void); + + virtual int do_base (void); + + virtual int do_current_number (void); + + virtual void do_stifle (int); + + virtual int do_unstifle (void); + + virtual int do_is_stifled (void); + + virtual void do_set_mark (int); + + virtual void do_goto_mark (void); + + virtual void do_read (bool); + + virtual void do_read (const string&, bool); + + virtual void do_read_range (int, int, bool); + + virtual void do_read_range (const string&, int, int, bool); + + virtual void do_write (const string&); + + virtual void do_append (const string&); + + virtual void do_truncate_file (const string&, int); + + virtual string_vector do_list (int, bool); + + virtual string do_get_entry (int); + + virtual void do_replace_entry (int, const string&); + + virtual void do_clean_up_and_save (const string&, int); + + void error (int); + + void error (const string&); // TRUE means we are ignoring new additions. bool ignoring_additions; @@ -106,14 +199,6 @@ // The number of lines of history to save. int xsize; - - void error (int); - - void error (const string&); - - command_history (const command_history&); - - command_history& operator = (const command_history&); }; #endif
--- a/liboctave/dir-ops.cc +++ b/liboctave/dir-ops.cc @@ -25,11 +25,14 @@ #endif #include <cerrno> +#include <cstdlib> #include <cstring> #include "sysdir.h" #include "dir-ops.h" +#include "lo-error.h" +#include "lo-sysdep.h" #include "str-vec.h" bool
--- a/liboctave/file-ops.cc +++ b/liboctave/file-ops.cc @@ -29,224 +29,43 @@ #include <cstdlib> #include <cstring> -#ifdef HAVE_UNISTD_H +#include <iostream.h> + #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif + +#ifdef HAVE_UNISTD_H #include <unistd.h> #endif -#include "error.h" +#ifdef HAVE_PWD_H +#include <pwd.h> +#endif + #include "file-ops.h" #include "lo-error.h" +#include "oct-env.h" #include "statdefs.h" - -// These must come after <sys/types.h> and <sys/stat.h>. - -#include <safe-lstat.h> -#include <safe-stat.h> - -// XXX FIXME XXX -- the is_* and mode_as_string functions are only valid -// for initialized objects. If called for an object that is not -// initialized, they should throw an exception. - -bool -file_stat::is_blk (void) const -{ -#ifdef S_ISBLK - return S_ISBLK (fs_mode); -#else - return false; -#endif -} - -bool -file_stat::is_chr (void) const -{ -#ifdef S_ISCHR - return S_ISCHR (fs_mode); -#else - return false; -#endif -} - -bool -file_stat::is_dir (void) const -{ -#ifdef S_ISDIR - return S_ISDIR (fs_mode); -#else - return false; -#endif -} - -bool -file_stat::is_fifo (void) const -{ -#ifdef S_ISFIFO - return S_ISFIFO (fs_mode); -#else - return false; -#endif -} - -bool -file_stat::is_lnk (void) const -{ -#ifdef S_ISLNK - return S_ISLNK (fs_mode); -#else - return false; -#endif -} - -bool -file_stat::is_reg (void) const -{ -#ifdef S_ISREG - return S_ISREG (fs_mode); -#else - return false; -#endif -} - -bool -file_stat::is_sock (void) const -{ -#ifdef S_ISSOCK - return S_ISSOCK (fs_mode); -#else - return false; -#endif -} - -extern "C" void mode_string (); - -string -file_stat::mode_as_string (void) const -{ - char buf[11]; - - mode_string (fs_mode, buf); - - buf[10] = '\0'; - - return string (buf); -} - -// Private stuff: - -void -file_stat::update_internal (bool force) -{ - if (! initialized || force) - { - initialized = false; - fail = false; - - const char *cname = file_name.c_str (); - - struct stat buf; - - int status = follow_links - ? SAFE_STAT (cname, &buf) : SAFE_LSTAT (cname, &buf); - - if (status < 0) - { - fail = true; - errmsg = strerror (errno); - } - else - { - fs_mode = buf.st_mode; - fs_ino = buf.st_ino; - fs_dev = buf.st_dev; - fs_nlink = buf.st_nlink; - fs_uid = buf.st_uid; - fs_gid = buf.st_gid; - fs_size = buf.st_size; - fs_atime = buf.st_atime; - fs_mtime = buf.st_mtime; - fs_ctime = buf.st_ctime; - -#if defined (HAVE_ST_RDEV) - fs_rdev = buf.st_rdev; -#endif - -#if defined (HAVE_ST_BLKSIZE) - fs_blksize = buf.st_blksize; -#endif - -#if defined (HAVE_ST_BLOCKS) - fs_blocks = buf.st_blocks; -#endif - } - - initialized = true; - } -} - -void -file_stat::copy (const file_stat& fs) -{ - file_name = fs.file_name; - follow_links = fs.follow_links; - initialized = fs.initialized; - fail = fs.fail; - errmsg = fs.errmsg; - fs_mode = fs.fs_mode; - fs_ino = fs.fs_ino; - fs_dev = fs.fs_dev; - fs_nlink = fs.fs_nlink; - fs_uid = fs.fs_uid; - fs_gid = fs.fs_gid; - fs_size = fs.fs_size; - fs_atime = fs.fs_atime; - fs_mtime = fs.fs_mtime; - fs_ctime = fs.fs_ctime; - -#if defined (HAVE_ST_RDEV) - fs_rdev = fs.fs_rdev; -#endif - -#if defined (HAVE_ST_BLKSIZE) - fs_blksize = fs.fs_blksize; -#endif - -#if defined (HAVE_ST_BLOCKS) - fs_blocks = fs.fs_blocks; -#endif -} - -// Functions for octave. - -// Has FILE been modified since TIME? Returns 1 for yes, 0 for no, -// and -1 for any error. -int -is_newer (const string& file, time_t time) -{ - file_stat fs (file); - - return fs ? fs.is_newer (time) : -1; -} +#include "str-vec.h" // We provide a replacement for mkdir(). int -oct_mkdir (const string& name, mode_t mode) +file_ops::mkdir (const string& name, mode_t mode) { - return mkdir (name.c_str (), mode); + return ::mkdir (name.c_str (), mode); } int -oct_mkdir (const string& name, mode_t mode, string& msg) +file_ops::mkdir (const string& name, mode_t mode, string& msg) { msg = string (); - int status = mkdir (name.c_str (), mode); + int status = ::mkdir (name.c_str (), mode); if (status < 0) - msg = strerror (errno); + msg = ::strerror (errno); return status; } @@ -254,30 +73,32 @@ // I don't know how to emulate this on systems that don't provide it. int -oct_mkfifo (const string& name, mode_t mode) +file_ops::mkfifo (const string& name, mode_t mode) { #if defined (HAVE_MKFIFO) - return mkfifo (name.c_str (), mode); + return ::mkfifo (name.c_str (), mode); #else - ::error ("mkfifo: not implemented on this system"); + (*current_liboctave_error_handler) + ("mkfifo: not implemented on this system"); return -1; #endif } int -oct_mkfifo (const string& name, mode_t mode, string& msg) +file_ops::mkfifo (const string& name, mode_t mode, string& msg) { msg = string (); #if defined (HAVE_MKFIFO) - int status = mkfifo (name.c_str (), mode); + int status = ::mkfifo (name.c_str (), mode); if (status < 0) - msg = strerror (errno); + msg = ::strerror (errno); return status; #else - ::error ("mkfifo: not implemented on this system"); + (*current_liboctave_error_handler) + ("mkfifo: not implemented on this system"); return -1; #endif } @@ -285,20 +106,20 @@ // We provide a replacement for rename(). int -oct_rename (const string& from, const string& to) +file_ops::rename (const string& from, const string& to) { - return rename (from.c_str (), to.c_str ()); + return ::rename (from.c_str (), to.c_str ()); } int -oct_rename (const string& from, const string& to, string& msg) +file_ops::rename (const string& from, const string& to, string& msg) { msg = string (); - int status = rename (from.c_str (), to.c_str ()); + int status = ::rename (from.c_str (), to.c_str ()); if (status < 0) - msg = strerror (errno); + msg = ::strerror (errno); return status; } @@ -306,20 +127,20 @@ // We provide a replacement for rmdir(). int -oct_rmdir (const string& name) +file_ops::rmdir (const string& name) { - return rmdir (name.c_str ()); + return ::rmdir (name.c_str ()); } int -oct_rmdir (const string& name, string& msg) +file_ops::rmdir (const string& name, string& msg) { msg = string (); - int status = rmdir (name.c_str ()); + int status = ::rmdir (name.c_str ()); if (status < 0) - msg = strerror (errno); + msg = ::strerror (errno); return status; } @@ -327,11 +148,11 @@ // We provide a replacement for tempnam(). string -oct_tempnam (void) +file_ops::tempnam (void) { string retval; - char *tmp = tempnam (0, "oct-"); + char *tmp = ::tempnam (0, "oct-"); if (tmp) { @@ -345,32 +166,119 @@ return retval; } +// If NAME has a leading ~ or ~user, Unix-style, expand it to the +// user's home directory. If no ~, or no <pwd.h>, just return NAME. + +// Mostly stolen from kpathsea. Readline also has a more complicated +// tilde-expand function, but we can probalby get by with something a +// bit simpler. + +// XXX FIXME XXX +#define DIR_SEP_CHAR '/' + +string +file_ops::tilde_expand (const string& name) +{ + string expansion = name; + +#if defined (HAVE_PWD_H) + + // If no leading tilde, do nothing. + + size_t beg = name.find_first_not_of (" \t"); + + if (beg != NPOS && name[beg] == '~') + { + // If `~' or `~/', use $HOME if it exists, or `.' if it doesn't. + + // If `~user' or `~user/', look up user in the passwd database. + + size_t len = name.length (); + + if (beg == len-1 || name[beg+1] == DIR_SEP_CHAR) + { + string home = octave_env::get_home_directory (); + + if (home.empty ()) + home = "."; + + expansion = name.substr (0, beg) + home; + + if (beg < len) + expansion.append (name.substr (beg+1)); + } + else + { + size_t end = name.find (DIR_SEP_CHAR, beg); + + size_t len = end; + + if (len != NPOS) + len -= beg + 1; + + string user = name.substr (beg+1, len); + + struct passwd *p + = static_cast<struct passwd *> (::getpwnam (user.c_str ())); + + // If no such user, just use `.'. + + string home = p ? p->pw_dir : "."; + + expansion = string (" ", beg) + home; + + if (end != NPOS) + expansion.append (name.substr (end)); + } + } + +#endif + + return expansion; +} + +// A vector version of the above. + +string_vector +file_ops::tilde_expand (const string_vector& names) +{ + string_vector retval; + + int n = names.length (); + + retval.resize (n); + + for (int i = 0; i < n; i++) + retval[i] = file_ops::tilde_expand (names[i]); + + return retval; +} int -oct_umask (mode_t mode) +file_ops::umask (mode_t mode) { #if defined (HAVE_UMASK) - return umask (mode); + return ::umask (mode); #else return 0; #endif } int -oct_unlink (const string& name) +file_ops::unlink (const string& name) { - return unlink (name.c_str ()); + return ::unlink (name.c_str ()); } int -oct_unlink (const string& name, string& errmsg) +file_ops::unlink (const string& name, string& errmsg) { errmsg = string (); - int status = unlink (name.c_str ()); + int status = ::unlink (name.c_str ()); if (status < 0) - errmsg = strerror (errno); + errmsg = ::strerror (errno); return status; }
--- a/liboctave/file-ops.h +++ b/liboctave/file-ops.h @@ -25,192 +25,37 @@ #include <string> +class string_vector; + #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif -class -file_stat +struct +file_ops { -public: - - file_stat (const string& n = string (), bool fl = true) - : file_name (n), follow_links (fl), initialized (false) - { - if (! file_name.empty ()) - update_internal (); - } - - file_stat (const file_stat& f) { copy (f); } - - file_stat& operator = (const file_stat& f) - { - if (this != &f) - copy (f); - - return *this; - } - - ~file_stat (void) { } - - void get_stats (bool force = false) - { - if (! initialized || force) - update_internal (force); - } - - void get_stats (const string& n, bool force = false) - { - if (n != file_name || ! initialized || force) - { - initialized = false; - - file_name = n; - - update_internal (force); - } - } - - // File status and info. These should only be called for objects - // that are already properly initialized. + static int mkdir (const string&, mode_t); + static int mkdir (const string&, mode_t, string&); - bool is_blk (void) const; - bool is_chr (void) const; - bool is_dir (void) const; - bool is_fifo (void) const; - bool is_lnk (void) const; - bool is_reg (void) const; - bool is_sock (void) const; - - ino_t ino (void) const { return fs_ino; } - dev_t dev (void) const { return fs_dev; } - - nlink_t nlink (void) const { return fs_nlink; } - - uid_t uid (void) const { return fs_uid; } - gid_t gid (void) const { return fs_gid; } - - off_t size (void) const { return fs_size; } - - time_t atime (void) const { return fs_atime; } - time_t mtime (void) const { return fs_mtime; } - time_t ctime (void) const { return fs_ctime; } + static int mkfifo (const string&, mode_t); + static int mkfifo (const string&, mode_t, string&); -#if defined (HAVE_ST_RDEV) - dev_t rdev (void) const { return fs_rdev; } -#endif - -#if defined (HAVE_ST_BLKSIZE) - long blksize (void) const { return fs_blksize; } -#endif - -#if defined (HAVE_ST_BLOCKS) - long blocks (void) const { return fs_blocks; } -#endif - - string mode_as_string (void) const; - - bool ok (void) const { return initialized && ! fail; } - - operator void* () const - { return ok () - ? static_cast<void *> (-1) : static_cast<void *> (0); } - - bool exists (void) const { return ok (); } - - string error (void) const { return ok () ? string () : errmsg; } + static int rename (const string&, const string&); + static int rename (const string&, const string&, string&); - // Has the file referenced by this object been modified since TIME? - bool is_newer (time_t time) const { return fs_mtime > time; } - -private: - - // Name of the file. - string file_name; - - // TRUE means follow symbolic links to the ultimate file (stat). - // FALSE means get information about the link itself (lstat). - bool follow_links; - - // TRUE means we have already called stat. - bool initialized; - - // TRUE means the stat for this file failed. - bool fail; - - // If a failure occurs, this contains the system error text. - string errmsg; + static int rmdir (const string&); + static int rmdir (const string&, string&); - // file type and permissions - mode_t fs_mode; - - // serial number - ino_t fs_ino; - - // device number - dev_t fs_dev; - - // number of links - nlink_t fs_nlink; - - // user ID of owner - uid_t fs_uid; - - // group ID of owner - gid_t fs_gid; - - // size in bytes, for regular files - off_t fs_size; - - // time of last access - time_t fs_atime; + static string tempnam (void); - // time of last modification - time_t fs_mtime; - - // time of last file status change - time_t fs_ctime; - -#if defined (HAVE_ST_RDEV) - // device number for special files - dev_t fs_rdev; -#endif - -#if defined (HAVE_ST_BLKSIZE) - // best I/O block size - long fs_blksize; -#endif - -#if defined (HAVE_ST_BLOCKS) - // number of 512-byte blocks allocated - long fs_blocks; -#endif - - void update_internal (bool force = false); + static string tilde_expand (const string&); + static string_vector tilde_expand (const string_vector&); - void copy (const file_stat&); -}; - -extern int is_newer (const string&, time_t); - -extern int oct_mkdir (const string&, mode_t); -extern int oct_mkdir (const string&, mode_t, string&); - -extern int oct_mkfifo (const string&, mode_t); -extern int oct_mkfifo (const string&, mode_t, string&); + static int umask (mode_t); -extern int oct_rename (const string&, const string&); -extern int oct_rename (const string&, const string&, string&); - -extern int oct_rmdir (const string&); -extern int oct_rmdir (const string&, string&); - -extern string oct_tempnam (void); - -extern int oct_umask (mode_t); - -extern int oct_unlink (const string&); -extern int oct_unlink (const string&, string&); + static int unlink (const string&); + static int unlink (const string&, string&); +}; #endif
new file mode 100644 --- /dev/null +++ b/liboctave/file-stat.cc @@ -0,0 +1,232 @@ +/* + +Copyright (C) 1996, 1997 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <cerrno> +#include <cstring> + +#ifdef HAVE_UNISTD_H +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#include <unistd.h> +#endif + +#include "file-stat.h" +#include "statdefs.h" + +// These must come after <sys/types.h> and <sys/stat.h>. + +#include <safe-lstat.h> +#include <safe-stat.h> + +// XXX FIXME XXX -- the is_* and mode_as_string functions are only valid +// for initialized objects. If called for an object that is not +// initialized, they should throw an exception. + +bool +file_stat::is_blk (void) const +{ +#ifdef S_ISBLK + return S_ISBLK (fs_mode); +#else + return false; +#endif +} + +bool +file_stat::is_chr (void) const +{ +#ifdef S_ISCHR + return S_ISCHR (fs_mode); +#else + return false; +#endif +} + +bool +file_stat::is_dir (void) const +{ +#ifdef S_ISDIR + return S_ISDIR (fs_mode); +#else + return false; +#endif +} + +bool +file_stat::is_fifo (void) const +{ +#ifdef S_ISFIFO + return S_ISFIFO (fs_mode); +#else + return false; +#endif +} + +bool +file_stat::is_lnk (void) const +{ +#ifdef S_ISLNK + return S_ISLNK (fs_mode); +#else + return false; +#endif +} + +bool +file_stat::is_reg (void) const +{ +#ifdef S_ISREG + return S_ISREG (fs_mode); +#else + return false; +#endif +} + +bool +file_stat::is_sock (void) const +{ +#ifdef S_ISSOCK + return S_ISSOCK (fs_mode); +#else + return false; +#endif +} + +extern "C" void mode_string (); + +string +file_stat::mode_as_string (void) const +{ + char buf[11]; + + mode_string (fs_mode, buf); + + buf[10] = '\0'; + + return string (buf); +} + +// Has FILE been modified since TIME? Returns 1 for yes, 0 for no, +// and -1 for any error. + +int +file_stat::is_newer (const string& file, time_t time) +{ + file_stat fs (file); + + return fs ? fs.is_newer (time) : -1; +} + +// Private stuff: + +void +file_stat::update_internal (bool force) +{ + if (! initialized || force) + { + initialized = false; + fail = false; + + const char *cname = file_name.c_str (); + + struct stat buf; + + int status = follow_links + ? SAFE_STAT (cname, &buf) : SAFE_LSTAT (cname, &buf); + + if (status < 0) + { + fail = true; + errmsg = strerror (errno); + } + else + { + fs_mode = buf.st_mode; + fs_ino = buf.st_ino; + fs_dev = buf.st_dev; + fs_nlink = buf.st_nlink; + fs_uid = buf.st_uid; + fs_gid = buf.st_gid; + fs_size = buf.st_size; + fs_atime = buf.st_atime; + fs_mtime = buf.st_mtime; + fs_ctime = buf.st_ctime; + +#if defined (HAVE_ST_RDEV) + fs_rdev = buf.st_rdev; +#endif + +#if defined (HAVE_ST_BLKSIZE) + fs_blksize = buf.st_blksize; +#endif + +#if defined (HAVE_ST_BLOCKS) + fs_blocks = buf.st_blocks; +#endif + } + + initialized = true; + } +} + +void +file_stat::copy (const file_stat& fs) +{ + file_name = fs.file_name; + follow_links = fs.follow_links; + initialized = fs.initialized; + fail = fs.fail; + errmsg = fs.errmsg; + fs_mode = fs.fs_mode; + fs_ino = fs.fs_ino; + fs_dev = fs.fs_dev; + fs_nlink = fs.fs_nlink; + fs_uid = fs.fs_uid; + fs_gid = fs.fs_gid; + fs_size = fs.fs_size; + fs_atime = fs.fs_atime; + fs_mtime = fs.fs_mtime; + fs_ctime = fs.fs_ctime; + +#if defined (HAVE_ST_RDEV) + fs_rdev = fs.fs_rdev; +#endif + +#if defined (HAVE_ST_BLKSIZE) + fs_blksize = fs.fs_blksize; +#endif + +#if defined (HAVE_ST_BLOCKS) + fs_blocks = fs.fs_blocks; +#endif +} + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/
new file mode 100644 --- /dev/null +++ b/liboctave/file-stat.h @@ -0,0 +1,204 @@ +/* + +Copyright (C) 1996, 1997 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#if !defined (octave_file_stat_h) +#define octave_file_stat_h 1 + +#include <string> + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +class +file_stat +{ +public: + + file_stat (const string& n = string (), bool fl = true) + : file_name (n), follow_links (fl), initialized (false) + { + if (! file_name.empty ()) + update_internal (); + } + + file_stat (const file_stat& f) { copy (f); } + + file_stat& operator = (const file_stat& f) + { + if (this != &f) + copy (f); + + return *this; + } + + ~file_stat (void) { } + + void get_stats (bool force = false) + { + if (! initialized || force) + update_internal (force); + } + + void get_stats (const string& n, bool force = false) + { + if (n != file_name || ! initialized || force) + { + initialized = false; + + file_name = n; + + update_internal (force); + } + } + + // File status and info. These should only be called for objects + // that are already properly initialized. + + bool is_blk (void) const; + bool is_chr (void) const; + bool is_dir (void) const; + bool is_fifo (void) const; + bool is_lnk (void) const; + bool is_reg (void) const; + bool is_sock (void) const; + + ino_t ino (void) const { return fs_ino; } + dev_t dev (void) const { return fs_dev; } + + nlink_t nlink (void) const { return fs_nlink; } + + uid_t uid (void) const { return fs_uid; } + gid_t gid (void) const { return fs_gid; } + + off_t size (void) const { return fs_size; } + + time_t atime (void) const { return fs_atime; } + time_t mtime (void) const { return fs_mtime; } + time_t ctime (void) const { return fs_ctime; } + +#if defined (HAVE_ST_RDEV) + dev_t rdev (void) const { return fs_rdev; } +#endif + +#if defined (HAVE_ST_BLKSIZE) + long blksize (void) const { return fs_blksize; } +#endif + +#if defined (HAVE_ST_BLOCKS) + long blocks (void) const { return fs_blocks; } +#endif + + string mode_as_string (void) const; + + bool ok (void) const { return initialized && ! fail; } + + operator void* () const + { return ok () + ? static_cast<void *> (-1) : static_cast<void *> (0); } + + bool exists (void) const { return ok (); } + + string error (void) const { return ok () ? string () : errmsg; } + + // Has the file referenced by this object been modified since TIME? + bool is_newer (time_t time) const { return fs_mtime > time; } + + // It's nice to be able to hide the file_stat object if we don't + // really care about it. + static int is_newer (const string&, time_t); + +private: + + // Name of the file. + string file_name; + + // TRUE means follow symbolic links to the ultimate file (stat). + // FALSE means get information about the link itself (lstat). + bool follow_links; + + // TRUE means we have already called stat. + bool initialized; + + // TRUE means the stat for this file failed. + bool fail; + + // If a failure occurs, this contains the system error text. + string errmsg; + + // file type and permissions + mode_t fs_mode; + + // serial number + ino_t fs_ino; + + // device number + dev_t fs_dev; + + // number of links + nlink_t fs_nlink; + + // user ID of owner + uid_t fs_uid; + + // group ID of owner + gid_t fs_gid; + + // size in bytes, for regular files + off_t fs_size; + + // time of last access + time_t fs_atime; + + // time of last modification + time_t fs_mtime; + + // time of last file status change + time_t fs_ctime; + +#if defined (HAVE_ST_RDEV) + // device number for special files + dev_t fs_rdev; +#endif + +#if defined (HAVE_ST_BLKSIZE) + // best I/O block size + long fs_blksize; +#endif + +#if defined (HAVE_ST_BLOCKS) + // number of 512-byte blocks allocated + long fs_blocks; +#endif + + void update_internal (bool force = false); + + void copy (const file_stat&); +}; + +#endif + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/
--- a/liboctave/glob-match.cc +++ b/liboctave/glob-match.cc @@ -32,7 +32,7 @@ #include <string> #include "file-stat.h" -#include "oct-glob.h" +#include "glob-match.h" #include "str-vec.h" bool
--- a/liboctave/glob-match.h +++ b/liboctave/glob-match.h @@ -20,8 +20,8 @@ */ -#if !defined (octave_oct_glob_h) -#define octave_oct_glob_h 1 +#if !defined (octave_glob_match_h) +#define octave_glob_match_h 1 #include <string>
new file mode 100644 --- /dev/null +++ b/liboctave/lo-sysdep.cc @@ -0,0 +1,120 @@ +/* + +Copyright (C) 1996, 1997 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +/* + +The function gethostname was adapted from a similar function from GNU +Bash, the Bourne Again SHell, copyright (C) 1987, 1989, 1991 Free +Software Foundation, Inc. + +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <string> + +#include <iostream.h> + +#ifdef HAVE_UNISTD_H +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#include <unistd.h> +#endif + +#if ! defined (HAVE_GETHOSTNAME) && defined (HAVE_SYS_UTSNAME_H) +#include <sys/utsname.h> +#endif + +#include "pathlen.h" + +string +octave_getcwd (void) +{ + string retval; + char buf[MAXPATHLEN]; + +#if defined (__EMX__) + char *tmp = _getcwd2 (buf, MAXPATHLEN); +#else + char *tmp = getcwd (buf, MAXPATHLEN); +#endif + + if (tmp) + retval = tmp; + + return retval; +} + +int +octave_chdir (const string& path) +{ +#if defined (__EMX__) + int retval = -1; + + char *tmp_path = strsave (path.c_str ()); + + if (path.length () == 2 && path[1] == ':') + { + char *upper_case_dir_name = strupr (tmp_path); + _chdrive (upper_case_dir_name[0]); + if (_getdrive () == upper_case_dir_name[0]) + retval = _chdir2 ("/"); + } + else + retval = _chdir2 (tmp_path); + + delete [] tmp_path; + + return retval; +#else + return chdir (path.c_str ()); +#endif +} + +#if ! defined (HAVE_GETHOSTNAME) && defined (HAVE_SYS_UTSNAME_H) + +int +gethostname (char *name, int namelen) +{ + int i; + struct utsname ut; + + --namelen; + + uname (&ut); + i = strlen (ut.nodename) + 1; + strncpy (name, ut.nodename, i < namelen ? i : namelen); + name[namelen] = '\0'; + + return 0; +} + +#endif + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/
new file mode 100644 --- /dev/null +++ b/liboctave/lo-sysdep.h @@ -0,0 +1,44 @@ +/* + +Copyright (C) 1996, 1997 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#if !defined (octave_liboctave_sysdep_h) +#define octave_liboctave_sysdep_h 1 + +#include <string> + +#include "lo-ieee.h" + +extern string octave_getcwd (void); + +extern bool octave_chdir (const string&); + +#if ! defined (HAVE_GETHOSTNAME) && defined (HAVE_SYS_UTSNAME_H) +extern int gethostname (char *, int); +#endif + +#endif + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/
--- a/liboctave/lo-utils.cc +++ b/liboctave/lo-utils.cc @@ -26,7 +26,19 @@ #endif #include <climits> +#include <cstdlib> +#include <cstdio> +#include <string> + +#ifdef HAVE_UNISTD_H +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#include <unistd.h> +#endif + +#include "lo-error.h" #include "lo-mappers.h" #include "lo-utils.h" @@ -53,6 +65,103 @@ return floor (x + 0.5); } +// Save a string. + +char * +strsave (const char *s) +{ + if (! s) + return 0; + + int len = strlen (s); + char *tmp = new char [len+1]; + tmp = strcpy (tmp, s); + return tmp; +} + +// This function was adapted from xputenv from Karl Berry's kpathsearch +// library. + +// XXX FIXME XXX -- make this do the right thing if we don't have a +// SMART_PUTENV. + +void +octave_putenv (const string& name, const string& value) +{ + int new_len = name.length () + value.length () + 2; + + char *new_item = static_cast<char*> (malloc (new_len)); + + sprintf (new_item, "%s=%s", name.c_str (), value.c_str ()); + + // As far as I can see there's no way to distinguish between the + // various errors; putenv doesn't have errno values. + + if (putenv (new_item) < 0) + (*current_liboctave_error_handler) ("putenv (%s) failed", new_item); +} + +string +octave_fgets (FILE *f) +{ + string retval; + + int grow_size = 1024; + int max_size = grow_size; + + char *buf = static_cast<char *> (malloc (max_size)); + char *bufptr = buf; + int len = 0; + + do + { + if (fgets (bufptr, grow_size, f)) + { + len = strlen (bufptr); + + if (len == grow_size - 1) + { + int tmp = bufptr - buf + grow_size - 1; + grow_size *= 2; + max_size += grow_size; + buf = static_cast<char *> (realloc (buf, max_size)); + bufptr = buf + tmp; + + if (*(bufptr-1) == '\n') + { + *bufptr = '\0'; + retval = buf; + } + } + else if (bufptr[len-1] != '\n') + { + bufptr[len++] = '\n'; + bufptr[len] = '\0'; + retval = buf; + } + else + retval = buf; + } + else + { + if (len == 0) + { + free (buf); + + buf = 0; + } + + break; + } + } + while (retval.empty ()); + + if (buf) + free (buf); + + return retval; +} + /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/liboctave/lo-utils.h +++ b/liboctave/lo-utils.h @@ -23,9 +23,19 @@ #if !defined (octave_liboctave_utils_h) #define octave_liboctave_utils_h 1 +#include <cstdio> + +#include <string> + extern int NINT (double x); extern double D_NINT (double x); +extern char *strsave (const char *); + +extern void octave_putenv (const string&, const string&); + +extern string octave_fgets (FILE *); + #endif /*
--- a/liboctave/mach-info.cc +++ b/liboctave/mach-info.cc @@ -70,7 +70,7 @@ } void -oct_mach_info::init_float_format (void) +oct_mach_info::init_float_format (void) const { float_params fp[5]; @@ -124,7 +124,7 @@ } void -oct_mach_info::ten_little_endians (void) +oct_mach_info::ten_little_endians (void) const { // Are we little or big endian? From Harbison & Steele. @@ -145,31 +145,44 @@ ten_little_endians (); } +bool +oct_mach_info::instance_ok (void) +{ + bool retval = true; + + if (! instance) + instance = new oct_mach_info (); + + if (! instance) + { + (*current_liboctave_error_handler) + ("unable to create command history object!"); + + retval = false; + } + + return retval; +} + oct_mach_info::float_format oct_mach_info::native_float_format (void) { - if (! instance) - instance = new oct_mach_info (); - - return instance->native_float_fmt; + return (instance_ok ()) + ? instance->native_float_fmt : oct_mach_info::unknown; } bool oct_mach_info::words_big_endian (void) { - if (! instance) - instance = new oct_mach_info (); - - return instance->big_chief; + return (instance_ok ()) + ? instance->big_chief : false; } bool oct_mach_info::words_little_endian (void) { - if (! instance) - instance = new oct_mach_info (); - - return ! instance->big_chief; + return (instance_ok ()) + ? (! instance->big_chief) : false; } oct_mach_info::float_format
--- a/liboctave/mach-info.h +++ b/liboctave/mach-info.h @@ -28,6 +28,10 @@ class oct_mach_info { +protected: + + oct_mach_info (void); + public: enum float_format @@ -41,7 +45,7 @@ cray }; - oct_mach_info (void); + static bool instance_ok (void); static float_format native_float_format (void); @@ -57,15 +61,15 @@ static oct_mach_info *instance; - void init_float_format (void); + void init_float_format (void) const; - void ten_little_endians (void); + void ten_little_endians (void) const; // The floating point format for the current machine. - float_format native_float_fmt; + mutable float_format native_float_fmt; // TRUE if the byte order on this system is big endian. - bool big_chief; + mutable bool big_chief; // No copying!
new file mode 100644 --- /dev/null +++ b/liboctave/oct-env.cc @@ -0,0 +1,493 @@ +/* + +Copyright (C) 1996, 1997 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +/* + +The functions listed below were adapted from a similar functions +from GNU Bash, the Bourne Again SHell, copyright (C) 1987, 1989, 1991 +Free Software Foundation, Inc. + + octave_env::do_absolute_pathname + octave_env::do_base_pathname + octave_env::do_chdir + octave_env::do_getcwd + octave_env::do_make_absolute + octave_env::do_polite_directory_format + octave_env::pathname_backup + +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <cerrno> +#include <cstdlib> + +#ifdef HAVE_UNISTD_H +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#include <unistd.h> +#endif + +#ifdef HAVE_PWD_H +#include <pwd.h> +#endif + +#include "lo-error.h" +#include "lo-sysdep.h" +#include "lo-utils.h" +#include "oct-env.h" + +octave_env::octave_env (void) + : follow_symbolic_links (true), verbatim_pwd (true), + current_directory (), program_name (), program_invocation_name (), + user_name (), host_name () +{ + // Get a real value for the current directory. + do_getcwd (); + + // Etc. + do_get_user_name (); + + do_get_host_name (); +} + +octave_env *octave_env::instance = 0; + +bool +octave_env::instance_ok (void) +{ + bool retval = true; + + if (! instance) + instance = new octave_env (); + + if (! instance) + { + (*current_liboctave_error_handler) + ("unable to create current working directoy object!"); + + retval = false; + } + + return retval; +} + +string +octave_env::polite_directory_format (const string& name) +{ + return (instance_ok ()) + ? instance->do_polite_directory_format (name) : string (); +} + +bool +octave_env::absolute_pathname (const string& s) +{ + return (instance_ok ()) + ? instance->do_absolute_pathname (s) : false; +} + +string +octave_env::base_pathname (const string& s) +{ + return (instance_ok ()) + ? instance->do_base_pathname (s) : string (); +} + +string +octave_env::make_absolute (const string& s, const string& dot_path) +{ + return (instance_ok ()) + ? instance->do_make_absolute (s, dot_path) : string (); +} + +string +octave_env::getcwd () +{ + return (instance_ok ()) + ? instance->do_getcwd () : string (); +} + +string +octave_env::get_home_directory () +{ + return (instance_ok ()) + ? instance->do_get_home_directory () : string (); +} + +string +octave_env::get_program_name (void) +{ + return (instance_ok ()) + ? instance->program_name : string (); +} + +string +octave_env::get_program_invocation_name (void) +{ + return (instance_ok ()) + ? instance->program_invocation_name : string (); +} + +void +octave_env::set_program_name (const string& s) +{ + if (instance_ok ()) + instance->do_set_program_name (s); +} + +string +octave_env::get_user_name (void) +{ + return (instance_ok ()) + ? instance->do_get_user_name () : string (); +} + +string +octave_env::get_host_name (void) +{ + return (instance_ok ()) + ? instance->do_get_host_name () : string (); +} + +// XXX FIXME XXX -- this leaves no way to distinguish between a +// variable that is not set and one that is set to the empty string. +// Is this a problem? + +string +octave_env::getenv (const string& name) +{ + return (instance_ok ()) + ? instance->do_getenv (name) : string (); +} + +void +octave_env::putenv (const string& name, const string& value) +{ + octave_putenv (name, value); +} + +bool +octave_env::chdir (const string& newdir) +{ + return (instance_ok ()) + ? instance->do_chdir (newdir) : false; +} + +void +octave_env::do_set_program_name (const string& s) const +{ + program_invocation_name = s; + + size_t pos = program_invocation_name.rfind ('/'); + + program_name = (pos == NPOS) + ? program_invocation_name : program_invocation_name.substr (pos+1); +} + +// Return a pretty pathname. If the first part of the pathname is the +// same as $HOME, then replace that with `~'. + +string +octave_env::do_polite_directory_format (const string& name) const +{ + string retval; + + string home_dir = do_get_home_directory (); + + size_t len = home_dir.length (); + + if (len > 1 && home_dir.compare (name, 0, len) == 0 + && (name.length () == len || name[len] == '/')) + { + retval = "~"; + retval.append (name.substr (len)); + } + else + retval = name; + + return retval; +} + +// Return 1 if STRING contains an absolute pathname, else 0. + +bool +octave_env::do_absolute_pathname (const string& s) const +{ + if (s.empty ()) + return 0; + + if (s[0] == '/') + return true; + + if (s[0] == '.') + { + if (s[1] == '\0' || s[1] == '/') + return true; + + if (s[1] == '.') + if (s[2] == '\0' || s[2] == '/') + return true; + } + + return false; +} + +// Return the `basename' of the pathname in STRING (the stuff after +// the last '/'). If STRING is not a full pathname, simply return it. + +string +octave_env::do_base_pathname (const string& s) const +{ + if (! do_absolute_pathname (s)) + return s; + + size_t pos = s.rfind ('/'); + + if (pos == NPOS) + return s; + else + return s.substr (pos+1); +} + +// Turn STRING (a pathname) into an absolute pathname, assuming that +// DOT_PATH contains the symbolic location of '.'. + +string +octave_env::do_make_absolute (const string& s, const string& dot_path) const +{ +#if defined (__EMX__) + if (s.length () > 1 && s[1] == ':') + return s; +#endif + + if (dot_path.empty () || s[0] == '/' || s.empty ()) + return s; + + string current_path = dot_path; + + if (current_path.empty ()) + current_path = "./"; + + size_t pos = current_path.length () - 1; + + if (current_path[pos] != '/') + current_path.append ("/"); + + size_t i = 0; + size_t slen = s.length (); + + while (i < slen) + { + if (s[i] == '.') + { + if (i + 1 == slen) + return current_path; + + if (s[i+1] == '/') + { + i += 2; + continue; + } + + if (s[i+1] == '.' && (i + 2 == slen || s[i+2] == '/')) + { + i += 2; + + if (i != slen) + i++; + + pathname_backup (current_path, 1); + + continue; + } + } + + size_t tmp = s.find ('/', i); + + if (tmp == NPOS) + { + current_path.append (s, i, tmp-i); + break; + } + else + { + current_path.append (s, i, tmp-i+1); + i = tmp + 1; + } + } + + return current_path; +} + +// Return a consed string which is the current working directory. + +string +octave_env::do_getcwd () +{ + if (! follow_symbolic_links) + current_directory = ""; + + if (verbatim_pwd || current_directory.empty ()) + current_directory = ::octave_getcwd (); + + return current_directory; +} + +// This value is not cached because it can change while Octave is +// running. + +string +octave_env::do_get_home_directory (void) const +{ + string hd = do_getenv ("HOME"); + + return hd.empty () ? string ("I have no home!") : hd; +} + +string +octave_env::do_get_user_name (void) const +{ + // XXX FIXME XXX -- is it possible for this to change while Octave + // is running? + + if (user_name.empty ()) + { + struct passwd *entry = getpwuid (getuid ()); + + user_name = entry ? entry->pw_name : "I have no name!"; + } + + return user_name; +} + +string +octave_env::do_get_host_name (void) const +{ + // XXX FIXME XXX -- is it possible for this to change while Octave + // is running? + + if (host_name.empty ()) + { + char hostname[256]; + + int status = gethostname (hostname, 255); + + host_name = (status < 0) ? "I have no host!" : hostname; + } + + return host_name; +} + +string +octave_env::do_getenv (const string& name) const +{ + char *value = ::getenv (name.c_str ()); + + return value ? value : ""; +} + +// Do the work of changing to the directory NEWDIR. Handle symbolic +// link following, etc. + +bool +octave_env::do_chdir (const string& newdir) +{ + bool retval = false; + + string tmp; + + if (follow_symbolic_links) + { + if (current_directory.empty ()) + do_getcwd (); + + if (current_directory.empty ()) + tmp = newdir; + else + tmp = do_make_absolute (newdir, current_directory); + + // Get rid of trailing `/'. + + size_t len = tmp.length (); + + if (len > 1) + { + if (tmp[--len] == '/') + tmp.resize (len); + } + + if (! ::octave_chdir (tmp)) + { + current_directory = tmp; + retval = true; + } + } + else + retval = (! ::octave_chdir (newdir)); + + return retval; +} + +// Remove the last N directories from PATH. + +void +octave_env::pathname_backup (string& path, int n) const +{ + if (path.empty ()) + return; + + size_t i = path.length () - 1; + + while (n--) + { + while (path[i] == '/' && i > 0) + i--; + + while (path[i] != '/' && i > 0) + i--; + + i++; + } + + path.resize (i); +} + +void +octave_env::error (int err_num) const +{ + (*current_liboctave_error_handler) ("%s", strerror (err_num)); +} + +void +octave_env::error (const string& s) const +{ + (*current_liboctave_error_handler) ("%s", s.c_str ()); +} + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/
new file mode 100644 --- /dev/null +++ b/liboctave/oct-env.h @@ -0,0 +1,135 @@ +/* + +Copyright (C) 1996, 1997 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#if !defined (octave_env_h) +#define octave_env_h 1 + +#include <string> + +class +octave_env +{ +protected: + + octave_env (void); + +public: + + static string polite_directory_format (const string& name); + + static bool absolute_pathname (const string& s); + + static string base_pathname (const string& s); + + static string make_absolute (const string& s, const string& dot_path); + + static string getcwd (void); + + static string get_home_directory (void); + + static string get_program_name (void); + + static string get_program_invocation_name (void); + + static string get_user_name (void); + + static string get_host_name (void); + + static string getenv (const string& name); + + static void putenv (const string& name, const string& value); + + static bool chdir (const string& newdir); + + static void set_program_name (const string& s); + +private: + + static bool instance_ok (void); + + string do_polite_directory_format (const string& name) const; + + bool do_absolute_pathname (const string& s) const; + + string do_base_pathname (const string& s) const; + + string do_make_absolute (const string& s, const string& dot_path) const; + + string do_getcwd (void); + + string do_get_home_directory (void) const; + + string do_get_user_name (void) const; + + string do_get_host_name (void) const; + + string do_getenv (const string& name) const; + + void do_putenv (const string& name, const string& value) const; + + bool do_chdir (const string& newdir); + + void do_set_program_name (const string& s) const; + + void pathname_backup (string& path, int n) const; + + void error (int) const; + + void error (const string&) const; + + // No copying! + + octave_env (const octave_env&); + + octave_env& operator = (const octave_env&); + + // The real thing. + static octave_env *instance; + + // TRUE means follow symbolic links that point to directories just + // as if they are real directories. + bool follow_symbolic_links; + + // TRUE means that pwd always give verbatim directory, regardless + // of symbolic link following. + bool verbatim_pwd; + + // Where are we? + string current_directory; + + // Etc. + mutable string program_name; + + mutable string program_invocation_name; + + mutable string user_name; + + mutable string host_name; +}; + +#endif + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/
--- a/liboctave/statdefs.h +++ b/liboctave/statdefs.h @@ -26,7 +26,10 @@ #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif + +#ifdef HAVE_SYS_STAT_H #include <sys/stat.h> +#endif #ifndef S_ISREG /* Doesn't have POSIX.1 stat stuff. */ #define mode_t unsigned short
--- a/liboctave/str-vec.cc +++ b/liboctave/str-vec.cc @@ -28,7 +28,7 @@ #include <iostream.h> -#include "oct-term.h" +#include "cmd-edit.h" #include "str-vec.h" // Create a string vector from a NULL terminated list of C strings. @@ -80,7 +80,7 @@ // Calculate the maximum number of columns that will fit. - int line_length = terminal_columns (); + int line_length = command_editor::terminal_cols (); int cols = line_length / max_name_length; if (cols == 0) cols = 1;
--- a/src/Makefile.in +++ b/src/Makefile.in @@ -162,7 +162,7 @@ -L../kpathsea -L../glob -L../dlfcn -L. $(RLD_FLAG) OCTAVE_LIBS = -loctinterp -loctave -ltinst -lcruft \ - $(LIBPLPLOT) -lreadline -lkpathsea -lglob $(LIBDLFCN) + $(LIBPLPLOT) $(LIBREADLINE) -lkpathsea -lglob $(LIBDLFCN) LIBS_TO_INSTALL = liboctinterp.a libtinst.a @@ -343,7 +343,7 @@ clean: rm -f *.a *.o *.d *.df *.oct pic/*.o - rm -f builtins.cc defaults.h oct-conf.h def-files var-files + rm -f builtins.cc ops.cc defaults.h oct-conf.h def-files var-files if $(SHARED_LIBS); then rm -f *.$(SHLEXT); fi .PHONY: clean
--- a/src/defaults.cc +++ b/src/defaults.cc @@ -45,6 +45,8 @@ #include <unistd.h> #endif +#include "oct-env.h" + #include <defaults.h> #include "defun.h" #include "error.h" @@ -106,9 +108,9 @@ static void set_octave_home (void) { - char *oh = getenv ("OCTAVE_HOME"); + string oh = octave_env::getenv ("OCTAVE_HOME"); - Voctave_home = oh ? string (oh) : string (OCTAVE_PREFIX); + Voctave_home = oh.empty () ? string (OCTAVE_PREFIX) : oh; } static void @@ -150,20 +152,20 @@ static void set_default_exec_path (void) { - char *octave_exec_path = getenv ("OCTAVE_EXEC_PATH"); + string octave_exec_path = octave_env::getenv ("OCTAVE_EXEC_PATH"); - if (octave_exec_path) - Vexec_path = string (octave_exec_path); - else + if (octave_exec_path.empty ()) { - char *shell_path = getenv ("PATH"); + string shell_path = octave_env::getenv ("PATH"); - if (shell_path) + if (! shell_path.empty ()) { Vexec_path = string (":"); Vexec_path.append (shell_path); } } + else + Vexec_path = string (octave_exec_path); } // Handle OCTAVE_PATH from the environment like TeX handles TEXINPUTS. @@ -176,9 +178,9 @@ { string std_path = subst_octave_home (OCTAVE_FCNFILEPATH); - char *oct_path = getenv ("OCTAVE_PATH"); + string oct_path = octave_env::getenv ("OCTAVE_PATH"); - Vload_path = oct_path ? string (oct_path) : std_path; + Vload_path = oct_path.empty () ? std_path : oct_path; } static void @@ -186,23 +188,23 @@ { string std_info_file = subst_octave_home (OCTAVE_INFOFILE); - char *oct_info_file = getenv ("OCTAVE_INFO_FILE"); + string oct_info_file = octave_env::getenv ("OCTAVE_INFO_FILE"); - Vinfo_file = oct_info_file ? string (oct_info_file) : std_info_file; + Vinfo_file = oct_info_file.empty () ? std_info_file : oct_info_file; } static void set_default_info_prog (void) { - char *oct_info_prog = getenv ("OCTAVE_INFO_PROGRAM"); + string oct_info_prog = octave_env::getenv ("OCTAVE_INFO_PROGRAM"); - if (oct_info_prog) - Vinfo_prog = string (oct_info_prog); - else + if (oct_info_prog.empty ()) { Vinfo_prog = Varch_lib_dir; Vinfo_prog.append ("/info"); } + else + Vinfo_prog = string (oct_info_prog); } static void @@ -210,10 +212,10 @@ { Veditor = "vi"; - char *env_editor = getenv ("EDITOR"); + string env_editor = octave_env::getenv ("EDITOR"); - if (env_editor && *env_editor) - Veditor = string (env_editor); + if (! env_editor.empty ()) + Veditor = env_editor; } static void @@ -326,59 +328,34 @@ std_path.append (SEPCHAR_STR); std_path.append (Varch_lib_dir); - int std_len = std_path.length (); - - static char *putenv_cmd = 0; - - delete [] putenv_cmd; - - putenv_cmd = 0; + string path; int eplen = Vexec_path.length (); if (eplen > 0) { - int prepend = (Vexec_path[0] == ':'); - int append = (eplen > 1 && Vexec_path[eplen-1] == ':'); + bool prepend = (Vexec_path[0] == ':'); + bool append = (eplen > 1 && Vexec_path[eplen-1] == ':'); if (prepend) { + path = std_path + Vexec_path; + if (append) - { - putenv_cmd = new char [2 * std_len + eplen + 6]; - sprintf (putenv_cmd, "PATH=%s%s%s", - std_path.c_str (), Vexec_path.c_str (), - std_path.c_str ()); - } - else - { - putenv_cmd = new char [std_len + eplen + 6]; - sprintf (putenv_cmd, "PATH=%s%s", - std_path.c_str (), Vexec_path.c_str ()); - } + path.append (std_path); } else { + path = Vexec_path; + if (append) - { - putenv_cmd = new char [std_len + eplen + 6]; - sprintf (putenv_cmd, "PATH=%s%s", - Vexec_path.c_str (), std_path.c_str ()); - } - else - { - putenv_cmd = new char [eplen + 6]; - sprintf (putenv_cmd, "PATH=%s", Vexec_path.c_str ()); - } + path.append (std_path); } } else - { - putenv_cmd = new char [std_len+6]; - sprintf (putenv_cmd, "PATH=%s", std_path.c_str ()); - } + path = std_path; - putenv (putenv_cmd); + octave_env::putenv ("PATH", path); } return status;
--- a/src/dirfns.cc +++ b/src/dirfns.cc @@ -20,19 +20,6 @@ */ -/* - -The functions listed below were adapted from a similar functions -from GNU Bash, the Bourne Again SHell, copyright (C) 1987, 1989, 1991 -Free Software Foundation, Inc. - - polite_directory_format absolute_pathname - base_pathname - make_absolute pathname_backup - change_to_directory get_working_directory - -*/ - #ifdef HAVE_CONFIG_H #include <config.h> #endif @@ -54,19 +41,20 @@ #include <unistd.h> #endif -#include "oct-glob.h" +#include "file-ops.h" +#include "file-stat.h" +#include "glob-match.h" +#include "oct-env.h" #include "str-vec.h" #include "defun.h" #include "dir-ops.h" #include "dirfns.h" #include "error.h" -#include "file-ops.h" #include "gripes.h" #include "help.h" #include "oct-obj.h" #include "pager.h" -#include "pathlen.h" #include "procstream.h" #include "pt-plot.h" #include "sysdep.h" @@ -75,239 +63,14 @@ #include "utils.h" #include "variables.h" -// The current working directory. -string Vcurrent_directory; - -// Non-zero means follow symbolic links that point to directories just -// as if they are real directories. -static int follow_symbolic_links = 1; - -// Non-zero means that pwd always give verbatim directory, regardless -// of symbolic link following. -static int verbatim_pwd = 1; - -// Remove the last N directories from PATH. Do not PATH blank. -// PATH must contain enough space for MAXPATHLEN characters. - -static void -pathname_backup (string& path, int n) -{ - if (path.empty ()) - return; - - size_t i = path.length () - 1; - - while (n--) - { - while (path[i] == '/' && i > 0) - i--; - - while (path[i] != '/' && i > 0) - i--; - - i++; - } - - path.resize (i); -} - -// Return a pretty pathname. If the first part of the pathname is the -// same as $HOME, then replace that with `~'. - -string -polite_directory_format (const string& name) -{ - string retval; - - size_t len = Vhome_directory.length (); - - if (len > 1 && Vhome_directory.compare (name, 0, len) == 0 - && (name.length () == len || name[len] == '/')) - { - retval = "~"; - retval.append (name.substr (len)); - } - else - retval = name; - - return retval; -} - -// Return 1 if STRING contains an absolute pathname, else 0. - -static int -absolute_pathname (const string& s) -{ - if (s.empty ()) - return 0; - - if (s[0] == '/') - return 1; - - if (s[0] == '.') - { - if (s[1] == '\0' || s[1] == '/') - return 1; - - if (s[1] == '.') - if (s[2] == '\0' || s[2] == '/') - return 1; - } - - return 0; -} - -// Return the `basename' of the pathname in STRING (the stuff after -// the last '/'). If STRING is not a full pathname, simply return it. - -string -base_pathname (const string& s) -{ - if (! absolute_pathname (s)) - return s; - - size_t pos = s.rfind ('/'); - - if (pos == NPOS) - return s; - else - return s.substr (pos+1); -} - -// Turn STRING (a pathname) into an absolute pathname, assuming that -// DOT_PATH contains the symbolic location of '.'. - -string -make_absolute (const string& s, const string& dot_path) -{ -#if defined (__EMX__) - if (s.length () > 1 && s[1] == ':') - return s; -#endif - - if (dot_path.empty () || s[0] == '/' || s.empty ()) - return s; - - string current_path = dot_path; - - if (current_path.empty ()) - current_path = "./"; - - size_t pos = current_path.length () - 1; - - if (current_path[pos] != '/') - current_path.append ("/"); - - size_t i = 0; - size_t slen = s.length (); - - while (i < slen) - { - if (s[i] == '.') - { - if (i + 1 == slen) - return current_path; - - if (s[i+1] == '/') - { - i += 2; - continue; - } - - if (s[i+1] == '.' && (i + 2 == slen || s[i+2] == '/')) - { - i += 2; - - if (i != slen) - i++; - - pathname_backup (current_path, 1); - - continue; - } - } - - size_t tmp = s.find ('/', i); - - if (tmp == NPOS) - { - current_path.append (s, i, tmp-i); - break; - } - else - { - current_path.append (s, i, tmp-i+1); - i = tmp + 1; - } - } - - return current_path; -} - -// Return a consed string which is the current working directory. -// FOR_WHOM is the name of the caller for error printing. - -string -get_working_directory (const string& for_whom) -{ - if (! follow_symbolic_links) - Vcurrent_directory = ""; - - if (Vcurrent_directory.empty ()) - { - Vcurrent_directory = octave_getcwd (); - - if (Vcurrent_directory.empty ()) - warning ("%s: can't find current directory!", for_whom.c_str ()); - } - - return Vcurrent_directory; -} - -// Do the work of changing to the directory NEWDIR. Handle symbolic -// link following, etc. - -static int -change_to_directory (const string& newdir) -{ - string tmp; - - if (follow_symbolic_links) - { - if (Vcurrent_directory.empty ()) - get_working_directory ("cd_links"); - - if (Vcurrent_directory.empty ()) - tmp = newdir; - else - tmp = make_absolute (newdir, Vcurrent_directory); - - // Get rid of trailing `/'. - - size_t len = tmp.length (); - - if (len > 1) - { - if (tmp[--len] == '/') - tmp.resize (len); - } - - if (octave_chdir (tmp) < 0) - return 0; - else - { - Vcurrent_directory = tmp; - return 1; - } - } - else - return (octave_chdir (newdir) < 0) ? 0 : 1; -} +// XXX FIXME XXX -- changing the plotter directory should be handled +// by registering a function for octave_env::chdir to call so that +// this function can be eliminated. static int octave_change_to_directory (const string& newdir) { - int cd_ok = change_to_directory (newdir); + int cd_ok = octave_env::chdir (newdir); if (cd_ok) do_external_plotter_cd (newdir); @@ -335,7 +98,7 @@ if (argc > 1) { - string dirname = oct_tilde_expand (argv[1]); + string dirname = file_ops::tilde_expand (argv[1]); if (dirname.length () > 0 && ! octave_change_to_directory (dirname)) @@ -345,16 +108,12 @@ } else { - if (Vhome_directory.empty () - || ! octave_change_to_directory (Vhome_directory)) - { - return retval; - } + string home_dir = octave_env::get_home_directory (); + + if (home_dir.empty () || ! octave_change_to_directory (home_dir)) + return retval; } - string directory = get_working_directory ("cd"); - bind_builtin_variable ("PWD", directory, 1); - return retval; } @@ -386,7 +145,7 @@ ls_buf << "ls -C "; for (int i = 1; i < argc; i++) - ls_buf << oct_tilde_expand (argv[i]) << " "; + ls_buf << file_ops::tilde_expand (argv[i]) << " "; ls_buf << ends; char *ls_command = ls_buf.str (); @@ -417,19 +176,12 @@ "pwd (): print current working directory") { octave_value_list retval; - string directory; - if (verbatim_pwd) - { - directory = octave_getcwd (); + string directory = octave_env::getcwd (); - if (directory.empty ()) - warning ("pwd: can't find working directory!"); - } + if (directory.empty ()) + warning ("pwd: can't find working directory!"); else - directory = get_working_directory ("pwd"); - - if (! directory.empty ()) { if (nargout == 0) octave_stdout << directory << "\n"; @@ -463,7 +215,7 @@ gripe_wrong_type_arg ("readdir", args(0)); else { - dir_entry dir (oct_tilde_expand (dirname)); + dir_entry dir (file_ops::tilde_expand (dirname)); if (dir) { @@ -509,8 +261,8 @@ { string msg; - int status = oct_mkdir (oct_tilde_expand (dirname), - 0777, msg); + int status = file_ops::mkdir (file_ops::tilde_expand (dirname), + 0777, msg); retval(0) = static_cast<double> (status); @@ -547,7 +299,7 @@ { string msg; - int status = oct_rmdir (oct_tilde_expand (dirname), msg); + int status = file_ops::rmdir (file_ops::tilde_expand (dirname), msg); retval(0) = static_cast<double> (status); @@ -590,7 +342,7 @@ { string msg; - int status = oct_rename (from, to, msg); + int status = file_ops::rename (from, to, msg); retval(0) = static_cast<double> (status); @@ -623,7 +375,7 @@ gripe_wrong_type_arg ("glob", args(0)); else { - glob_match pattern (oct_tilde_expand (pat)); + glob_match pattern (file_ops::tilde_expand (pat)); string_vector list = pattern.glob (); @@ -657,7 +409,7 @@ gripe_wrong_type_arg ("fnmatch", args(0)); else { - glob_match pattern (oct_tilde_expand (pat)); + glob_match pattern (file_ops::tilde_expand (pat)); Array<bool> tmp = pattern.match (str); @@ -677,31 +429,6 @@ return retval; } -static int -pwd (void) -{ - int status = 0; - - string s = builtin_string_variable ("PWD"); - - if (s.empty ()) - { - gripe_invalid_value_specified ("PWD"); - status = -1; - } - else - Vcurrent_directory = s; - - return status; -} - -void -symbols_of_dirfns (void) -{ - DEFCONST (PWD, get_working_directory ("initialize_globals"), 0, pwd, - "current working directory"); -} - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/dynamic-ld.cc +++ b/src/dynamic-ld.cc @@ -181,33 +181,43 @@ #endif -static octave_dynamic_loader * -make_dynamic_loader (void) +octave_dynamic_loader *octave_dynamic_loader::instance = 0; + +bool +octave_dynamic_loader::instance_ok (void) +{ + bool retval = true; + + if (! instance) + make_dynamic_loader (); + + if (! instance) + { + error ("unable to create command history object!"); + + retval = false; + } + + return retval; +} + +void +octave_dynamic_loader::make_dynamic_loader (void) { #if defined (WITH_DL) - return new octave_dlopen_dynamic_loader (); + instance = new octave_dlopen_dynamic_loader (); #elif defined (WITH_SHL) - return new octave_sh_load_dynamic_loader (); + instance = new octave_sh_load_dynamic_loader (); #else - return new octave_dynamic_loader (); + instance = new octave_dynamic_loader (); #endif } -octave_dynamic_loader *octave_dynamic_loader::instance = 0; - -octave_dynamic_loader::octave_dynamic_loader (void) -{ -} - -octave_dynamic_loader::~octave_dynamic_loader (void) -{ -} - int octave_dynamic_loader::load_fcn_from_dot_oct_file (const string& fcn_name) { - if (! instance) - instance = make_dynamic_loader (); + if (! instance_ok ()) + make_dynamic_loader (); int retval = 0;
--- a/src/dynamic-ld.h +++ b/src/dynamic-ld.h @@ -32,30 +32,36 @@ { protected: - octave_dynamic_loader (void); + octave_dynamic_loader (void) { } public: typedef octave_builtin * (*builtin_fcn) (void); - virtual ~octave_dynamic_loader (void); + virtual ~octave_dynamic_loader (void) { } static int load_fcn_from_dot_oct_file (const string& fcn_name); private: - static octave_dynamic_loader *instance; - - virtual builtin_fcn - resolve_reference (const string& mangled_name, const string& oct_file); - - string mangle_name (const string& name); - // No copying! octave_dynamic_loader (const octave_dynamic_loader&); octave_dynamic_loader& operator = (const octave_dynamic_loader&); + + static octave_dynamic_loader *instance; + + static bool instance_ok (void); + + static void make_dynamic_loader (void); + +protected: + + virtual builtin_fcn + resolve_reference (const string& mangled_name, const string& oct_file); + + string mangle_name (const string& name); }; #endif
--- a/src/file-io.cc +++ b/src/file-io.cc @@ -49,9 +49,10 @@ #include <unistd.h> #endif +#include "file-ops.h" + #include "defun.h" #include "error.h" -#include "file-ops.h" #include "help.h" #include "lo-ieee.h" #include "oct-fstrm.h" @@ -1279,7 +1280,7 @@ octave_value retval; if (args.length () == 0) - retval = oct_tempnam (); + retval = file_ops::tempnam (); else print_usage ("tmpnam"); @@ -1353,7 +1354,7 @@ int oct_mask = convert (mask, 8, 10); if (! error_state) - status = convert (oct_umask (oct_mask), 10, 8); + status = convert (file_ops::umask (oct_mask), 10, 8); } } }
--- a/src/fn-cache.cc +++ b/src/fn-cache.cc @@ -26,7 +26,7 @@ #include <string> -#include "file-ops.h" +#include "file-stat.h" #include "str-vec.h" #include <defaults.h> @@ -84,7 +84,7 @@ if (instance) retval = instance->do_list (path, no_suffix); else - panic_impossible (); + error ("unable to create file name cache object!"); return retval; }
--- a/src/help.cc +++ b/src/help.cc @@ -41,6 +41,7 @@ #include <unistd.h> #endif +#include "oct-env.h" #include "str-vec.h" #include <defaults.h> @@ -509,9 +510,10 @@ if (! names.empty ()) { - octave_stdout << "\n*** function files in " - << make_absolute (dirs[i], Vcurrent_directory) - << ":\n\n"; + string dir + = octave_env::make_absolute (dirs[i], octave_env::getcwd ()); + + octave_stdout << "\n*** function files in " << dir << ":\n\n"; names.list_in_columns (octave_stdout); }
--- a/src/lex.l +++ b/src/lex.l @@ -37,6 +37,8 @@ #include "SLStack.h" +#include "cmd-edit.h" + // These would be alphabetical, but y.tab.h must be included before // oct-gperf.h and y.tab.h must be included after token.h and the tree // class declarations. We can't include y.tab.h in oct-gperf.h @@ -701,7 +703,7 @@ if (! (reading_script_file || reading_fcn_file)) { current_input_column = 1; - input_line_number = current_command_number - 1; + input_line_number = command_editor::current_command_number () - 1; } // Only ask for input from stdin if we are expecting interactive
--- a/src/load-save.cc +++ b/src/load-save.cc @@ -36,9 +36,10 @@ #include "byte-swap.h" #include "data-conv.h" +#include "file-ops.h" +#include "glob-match.h" #include "lo-mappers.h" #include "mach-info.h" -#include "oct-glob.h" #include "str-vec.h" #include "defun.h" @@ -1662,7 +1663,7 @@ } else { - string fname = oct_tilde_expand (argv[i]); + string fname = file_ops::tilde_expand (argv[i]); if (format == LS_UNKNOWN) format = get_file_format (fname, orig_fname); @@ -2466,7 +2467,7 @@ } else { - string fname = oct_tilde_expand (argv[i]); + string fname = file_ops::tilde_expand (argv[i]); i++;
--- a/src/oct-hist.cc +++ b/src/oct-hist.cc @@ -48,6 +48,7 @@ #include "cmd-hist.h" #include "file-ops.h" +#include "oct-env.h" #include "str-vec.h" #include <defaults.h> @@ -67,9 +68,6 @@ // Nonzero means input is coming from temporary history file. int input_from_tmp_history_file = 0; -// Guess what? -command_history octave_command_history; - // Get some default values, possibly reading them from the // environment. @@ -77,13 +75,17 @@ default_history_size (void) { int size = 1024; - char *env_size = getenv ("OCTAVE_HISTSIZE"); - if (env_size) + + string env_size = octave_env::getenv ("OCTAVE_HISTSIZE"); + + if (! env_size.empty ()) { int val; - if (sscanf (env_size, "%d", &val) == 1) + + if (sscanf (env_size.c_str (), "%d", &val) == 1) size = val > 0 ? val : 0; } + return size; } @@ -92,11 +94,11 @@ { string file; - char *env_file = getenv ("OCTAVE_HISTFILE"); + string env_file = octave_env::getenv ("OCTAVE_HISTFILE"); - if (env_file) + if (! env_file.empty ()) { - fstream f (env_file, (ios::in | ios::out)); + fstream f (env_file.c_str (), (ios::in | ios::out)); if (f) { @@ -107,9 +109,11 @@ if (file.empty ()) { - if (! Vhome_directory.empty ()) + string home_dir = octave_env::get_home_directory (); + + if (! home_dir.empty ()) { - file = Vhome_directory; + file = home_dir; file.append ("/.octave_hist"); } else @@ -140,25 +144,25 @@ { if (i < argc - 1) { - string file = oct_tilde_expand (argv[i+1]); - octave_command_history.set_file (file); + string file = file_ops::tilde_expand (argv[i+1]); + command_history::set_file (file); } if (option == "-a") // Append `new' lines to file. - octave_command_history.append (); + command_history::append (); else if (option == "-w") // Write entire history. - octave_command_history.write (); + command_history::write (); else if (option == "-r") // Read entire file. - octave_command_history.read (); + command_history::read (); else if (option == "-n") // Read `new' history from file. - octave_command_history.read_range (); + command_history::read_range (); else panic_impossible (); @@ -194,7 +198,7 @@ limit = -limit; } - string_vector hlist = octave_command_history.list (limit, numbered_output); + string_vector hlist = command_history::list (limit, numbered_output); int len = hlist.length (); @@ -267,7 +271,7 @@ { if (! command.empty ()) { - string_vector hlist = octave_command_history.list (); + string_vector hlist = command_history::list (); int len = hlist.length (); @@ -275,7 +279,7 @@ { int i = len - 1; - string histent = octave_command_history.get_entry (i); + string histent = command_history::get_entry (i); if (! histent.empty ()) { @@ -287,7 +291,7 @@ cmd.resize (cmd_len - 1); if (! cmd.empty ()) - octave_command_history.replace_entry (i, cmd); + command_history::replace_entry (i, cmd); } } } @@ -306,7 +310,7 @@ tmp.resize (len - 1); if (! tmp.empty ()) - octave_command_history.add (tmp); + command_history::add (tmp); } } @@ -316,7 +320,7 @@ { string retval; - string_vector hlist = octave_command_history.list (); + string_vector hlist = command_history::list (); int hist_count = hlist.length (); @@ -326,7 +330,7 @@ hist_count -= 2; if (! insert_curr) - octave_command_history.remove (hist_count); + command_history::remove (hist_count); hist_count--; @@ -383,7 +387,7 @@ reverse = 1; } - string name = oct_tempnam (); + string name = file_ops::tempnam (); fstream file (name.c_str (), ios::out);
--- a/src/oct-hist.h +++ b/src/oct-hist.h @@ -30,9 +30,6 @@ extern int default_history_size (void); extern string default_history_file (void); -// Guess what? -extern command_history octave_command_history; - // Nonzero means input is coming from temporary history file. extern int input_from_tmp_history_file;
--- a/src/oct-stream.cc +++ b/src/oct-stream.cc @@ -2366,6 +2366,92 @@ octave_stream_list *octave_stream_list::instance = 0; +bool +octave_stream_list::instance_ok (void) +{ + bool retval = true; + + if (! instance) + instance = new octave_stream_list (); + + if (! instance) + { + ::error ("unable to create stream list object!"); + + retval = false; + } + + return retval; +} + +octave_value +octave_stream_list::insert (octave_base_stream *obs) +{ + return (instance_ok ()) ? instance->do_insert (obs) : octave_value (-1.0); +} + +octave_stream * +octave_stream_list::lookup (int fid) +{ + return (instance_ok ()) ? instance->do_lookup (fid) : 0; +} + +octave_stream * +octave_stream_list::lookup (const octave_value& fid) +{ + return (instance_ok ()) ? instance->do_lookup (fid) : 0; +} + +int +octave_stream_list::remove (int fid) +{ + return (instance_ok ()) ? instance->do_remove (fid) : -1; +} + +int +octave_stream_list::remove (const octave_value& fid) +{ + return (instance_ok ()) ? instance->do_remove (fid) : -1; +} + +void +octave_stream_list::clear (void) +{ + if (instance) + instance->do_clear (); +} + +string_vector +octave_stream_list::get_info (int fid) +{ + return (instance_ok ()) ? instance->do_get_info (fid) : string_vector (); +} + +string_vector +octave_stream_list::get_info (const octave_value& fid) +{ + return (instance_ok ()) ? instance->do_get_info (fid) : string_vector (); +} + +string +octave_stream_list::list_open_files (void) +{ + return (instance_ok ()) ? instance->do_list_open_files () : string (); +} + +octave_value +octave_stream_list::open_file_numbers (void) +{ + return (instance_ok ()) + ? instance->do_open_file_numbers () : octave_value (); +} + +int +octave_stream_list::get_file_number (const octave_value& fid) +{ + return (instance_ok ()) ? instance->do_get_file_number (fid) : -1; +} + octave_value octave_stream_list::do_insert (octave_base_stream *obs) { @@ -2410,22 +2496,6 @@ return octave_value (os, stream_number); } -octave_value -octave_stream_list::insert (octave_base_stream *obs) -{ - octave_value retval = -1.0; - - if (! instance) - instance = new octave_stream_list (); - - if (instance) - retval = instance->do_insert (obs); - else - panic_impossible (); - - return retval; -} - octave_stream * octave_stream_list::do_lookup (int fid) const { @@ -2450,28 +2520,6 @@ return retval; } -octave_stream * -octave_stream_list::lookup (int fid) -{ - octave_stream *retval = 0; - - if (instance) - retval = instance->do_lookup (fid); - - return retval; -} - -octave_stream * -octave_stream_list::lookup (const octave_value& fid) -{ - octave_stream *retval = 0; - - if (instance) - retval = instance->do_lookup (fid); - - return retval; -} - int octave_stream_list::do_remove (int fid) { @@ -2507,28 +2555,6 @@ return retval; } -int -octave_stream_list::remove (int fid) -{ - int retval = -1; - - if (instance) - retval = instance->do_remove (fid); - - return retval; -} - -int -octave_stream_list::remove (const octave_value& fid) -{ - int retval = -1; - - if (instance) - retval = instance->do_remove (fid); - - return retval; -} - void octave_stream_list::do_clear (void) { @@ -2549,13 +2575,6 @@ } } -void -octave_stream_list::clear (void) -{ - if (instance) - instance->do_clear (); -} - string_vector octave_stream_list::do_get_info (int fid) const { @@ -2594,28 +2613,6 @@ return retval; } -string_vector -octave_stream_list::get_info (int fid) -{ - string_vector retval; - - if (instance) - retval = instance->do_get_info (fid); - - return retval; -} - -string_vector -octave_stream_list::get_info (const octave_value& fid) -{ - string_vector retval; - - if (instance) - retval = instance->do_get_info (fid); - - return retval; -} - string octave_stream_list::do_list_open_files (void) const { @@ -2658,17 +2655,6 @@ return retval; } -string -octave_stream_list::list_open_files (void) -{ - string retval; - - if (instance) - retval = instance->do_list_open_files (); - - return retval; -} - octave_value octave_stream_list::do_open_file_numbers (void) const { @@ -2689,17 +2675,6 @@ return retval; } -octave_value -octave_stream_list::open_file_numbers (void) -{ - octave_value retval; - - if (instance) - retval = instance->do_open_file_numbers (); - - return retval; -} - int octave_stream_list::do_get_file_number (const octave_value& fid) const { @@ -2737,17 +2712,6 @@ return retval; } -int -octave_stream_list::get_file_number (const octave_value& fid) -{ - int retval = -1; - - if (instance) - retval = instance->do_get_file_number (fid); - - return retval; -} - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/oct-stream.h +++ b/src/oct-stream.h @@ -494,6 +494,8 @@ ~octave_stream_list (void) { } + static bool instance_ok (void); + static octave_value insert (octave_base_stream *obs); static octave_stream *lookup (int fid);
--- a/src/octave.cc +++ b/src/octave.cc @@ -43,11 +43,10 @@ #include <unistd.h> #endif -#ifdef HAVE_PWD_H -#include <pwd.h> -#endif - +#include "cmd-edit.h" +#include "file-stat.h" #include "lo-error.h" +#include "oct-env.h" #include "str-vec.h" #include <defaults.h> @@ -55,7 +54,6 @@ #include "dynamic-ld.h" #include "error.h" #include "file-io.h" -#include "file-ops.h" #include "help.h" #include "input.h" #include "lex.h" @@ -92,11 +90,6 @@ char *program_invocation_short_name; #endif -#if defined (USE_READLINE) -// This is from readline's paren.c: -extern int rl_blink_matching_paren; -#endif - // The command-line options. static string_vector octave_argv; @@ -169,6 +162,18 @@ static void intern_argv (int argc, char **argv) { + octave_env::set_program_name (argv[0]); + + // XXX FIXME XXX -- Kpathsea needs this. + +#if ! defined (HAVE_PROGRAM_INVOCATION_NAME) + program_invocation_name + = strsave (octave_env::get_program_invocation_name () . c_str ()); + + program_invocation_short_name + = strsave (octave_env::get_program_name () . c_str ()); +#endif + if (argc > 1) { // Skip program name in argv. @@ -182,62 +187,28 @@ bind_builtin_variable ("nargin", static_cast<double> (argc-1), 1, 1, 0); } -// Initialize some global variables for later use. - -static void -initialize_globals (const string& name) -{ - // Kpathsea needs this. - -#if ! defined (HAVE_PROGRAM_INVOCATION_NAME) - program_invocation_name = strsave (name.c_str ()); - program_invocation_short_name = strrchr (program_invocation_name, '/'); - if (! program_invocation_short_name) - program_invocation_short_name = program_invocation_name; -#endif - - Vprogram_invocation_name = name; - size_t pos = Vprogram_invocation_name.rfind ('/'); - Vprogram_name = (pos == NPOS) - ? Vprogram_invocation_name : Vprogram_invocation_name.substr (pos+1); - - struct passwd *entry = getpwuid (getuid ()); - Vuser_name = entry ? entry->pw_name : "I have no name!"; - - char hostname[256]; - int status = gethostname (hostname, 255); - Vhost_name = (status < 0) ? "I have no host!" : hostname; - - char *hd = getenv ("HOME"); - Vhome_directory = hd ? hd : "I have no home!"; - - install_defaults (); -} - static void initialize_pathsearch (void) { // This may seem odd, but doing it this way means that we don't have // to modify the kpathsea library... - char *odb = getenv ("OCTAVE_DB_DIR"); + string odb = octave_env::getenv ("OCTAVE_DB_DIR"); - if (odb) - oct_putenv ("TEXMF", odb); - else + if (odb.empty ()) { - char *oh = getenv ("OCTAVE_HOME"); + string oh = octave_env::getenv ("OCTAVE_HOME"); - if (oh) + if (oh.empty ()) + octave_env::putenv ("TEXMF", OCTAVE_DATADIR "/octave"); + else { - int len = strlen (oh) + 12; - char *putenv_val = new char [len]; - sprintf (putenv_val, "%s/lib/octave", oh); - oct_putenv ("TEXMF", putenv_val); + oh.append ("/lib/octave"); + octave_env::putenv ("TEXMF", oh); } - else - oct_putenv ("TEXMF", OCTAVE_DATADIR "/octave"); } + else + octave_env::putenv ("TEXMF", odb); } // Initialize by reading startup files. @@ -276,15 +247,17 @@ int home_rc_already_executed = 0; - const char *initfile = getenv ("OCTAVE_INITFILE"); + string initfile = octave_env::getenv ("OCTAVE_INITFILE"); - if (! initfile) + if (initfile.empty ()) initfile = ".octaverc"; - string home_rc = Vhome_directory + "/" + initfile; + string home_dir = octave_env::get_home_directory (); + + string home_rc = home_dir + "/" + initfile; string local_rc = string ("./") + initfile; - if (! Vhome_directory.empty ()) + if (! home_dir.empty ()) { parse_and_execute (home_rc, verbose); @@ -396,7 +369,7 @@ main (int argc, char **argv) { // The order of these calls is important. The call to - // initialize_globals must come before install_builtins because + // install_defaults must come before install_builtins because // default variable values must be available for the varaibles to be // installed, and the call to install_builtins must come before the // options are processed because some command line options override @@ -406,7 +379,7 @@ initialize_error_handlers (); - initialize_globals (argv[0]); + install_defaults (); initialize_pathsearch (); @@ -491,7 +464,7 @@ break; case NO_LINE_EDITING_OPTION: - using_readline = false; + line_editing = 0; break; case NO_SITE_FILE_OPTION: @@ -521,7 +494,7 @@ // These can come after command line args since none of them set any // defaults that might be changed by command line options. - initialize_readline (); + initialize_command_input (); if (! inhibit_startup_message) cout << OCTAVE_STARTUP_MESSAGE "\n" << endl; @@ -531,14 +504,14 @@ execute_startup_files (); - octave_command_history.read (false); + command_history::read (false); if (! inhibit_startup_message && reading_startup_message_printed) cout << endl; // Avoid counting commands executed from startup files. - current_command_number = 1; + command_editor::reset_current_command_number (1); // If there is an extra argument, see if it names a file to read. // Additional arguments are taken as command line options for the @@ -570,7 +543,8 @@ intern_argv (remaining_args, argv+last_arg_idx); - rl_blink_matching_paren = 0; + command_editor::blink_matching_paren (false); + switch_to_buffer (create_buffer (infile)); } else @@ -593,7 +567,7 @@ if (! interactive && forced_interactive) { - rl_blink_matching_paren = 0; + command_editor::blink_matching_paren (false); // XXX FIXME XXX -- is this the right thing to do? @@ -602,7 +576,7 @@ } if (! interactive) - using_readline = 0; + line_editing = 0; int retval = main_loop ();
--- a/src/ov-typeinfo.cc +++ b/src/ov-typeinfo.cc @@ -56,13 +56,28 @@ template class Array<type_conv_fcn>; template class Array2<type_conv_fcn>; +bool +octave_value_typeinfo::instance_ok (void) +{ + bool retval = true; + if (! instance) + instance = new octave_value_typeinfo (); + + if (! instance) + { + ::error ("unable to create value type info object!"); + + retval = false; + } + + return retval; +} + int octave_value_typeinfo::register_type (const string& name) { - if (! instance) - instance = new octave_value_typeinfo (); - - return instance->do_register_type (name); + return (instance_ok ()) + ? instance->do_register_type (name) : -1; } bool @@ -70,10 +85,8 @@ int t1, int t2, binary_op_fcn f) { - if (! instance) - instance = new octave_value_typeinfo (); - - return instance->do_register_binary_op (op, t1, t2, f); + return (instance_ok ()) + ? instance->do_register_binary_op (op, t1, t2, f) : false; } bool @@ -81,30 +94,24 @@ int t_lhs, int t_rhs, assign_op_fcn f) { - if (! instance) - instance = new octave_value_typeinfo (); - - return instance->do_register_assign_op (op, t_lhs, t_rhs, f); + return (instance_ok ()) + ? instance->do_register_assign_op (op, t_lhs, t_rhs, f) : -1; } bool octave_value_typeinfo::register_pref_assign_conv (int t_lhs, int t_rhs, int t_result) { - if (! instance) - instance = new octave_value_typeinfo (); - - return instance->do_register_pref_assign_conv (t_lhs, t_rhs, t_result); + return (instance_ok ()) + ? instance->do_register_pref_assign_conv (t_lhs, t_rhs, t_result) : false; } bool octave_value_typeinfo::register_widening_op (int t, int t_result, type_conv_fcn f) { - if (! instance) - instance = new octave_value_typeinfo (); - - return instance->do_register_widening_op (t, t_result, f); + return (instance_ok ()) + ? instance->do_register_widening_op (t, t_result, f) : false; } int
--- a/src/ov-typeinfo.h +++ b/src/ov-typeinfo.h @@ -42,6 +42,8 @@ { public: + static bool instance_ok (void); + static int register_type (const string&); static bool register_binary_op (octave_value::binary_op, int, int,
--- a/src/pager.cc +++ b/src/pager.cc @@ -29,7 +29,8 @@ #include <string> #include <fstream.h> -#include "oct-term.h" +#include "cmd-edit.h" +#include "oct-env.h" #include "procstream.h" @@ -190,7 +191,7 @@ { if (s) { - int available_rows = terminal_rows () - 2; + int available_rows = command_editor::terminal_rows () - 2; int count = 0; @@ -271,7 +272,7 @@ { if (! instance) instance = new octave_pager_stream (); - + return *instance; } @@ -432,14 +433,10 @@ static string default_pager (void) { - string pager_binary; - - char *pgr = getenv ("PAGER"); + string pager_binary = octave_env::getenv ("PAGER"); - if (pgr) - pager_binary = string (pgr); #ifdef DEFAULT_PAGER - else + if (pager_binary.empty ()) { pager_binary = string (DEFAULT_PAGER); @@ -447,7 +444,8 @@ { pager_binary.append (" -e"); - if (! getenv ("LESS")) + string lessflags = octave_env::getenv ("LESS"); + if (lessflags.empty ()) pager_binary.append (" -P'-- less ?pB(%pB\\%):--. (f)orward, (b)ack, (q)uit$'"); }
--- a/src/pr-output.cc +++ b/src/pr-output.cc @@ -35,12 +35,12 @@ #include "CMatrix.h" #include "Range.h" +#include "cmd-edit.h" #include "dMatrix.h" #include "lo-mappers.h" #include "mach-info.h" #include "oct-cmplx.h" #include "oct-math.h" -#include "oct-term.h" #include "str-vec.h" #include "defun.h" @@ -1146,7 +1146,7 @@ set_format (m, fw); int column_width = fw + 2; int total_width = nc * column_width; - int max_width = terminal_columns (); + int max_width = command_editor::terminal_cols (); if (pr_as_read_syntax) max_width -= 4; @@ -1299,7 +1299,7 @@ int column_width = i_fw + r_fw; column_width += (bank_format || hex_format|| bit_format) ? 2 : 7; int total_width = nc * column_width; - int max_width = terminal_columns (); + int max_width = command_editor::terminal_cols (); if (pr_as_read_syntax) max_width -= 4; @@ -1447,7 +1447,7 @@ { int column_width = fw + 2; int total_width = num_elem * column_width; - int max_width = terminal_columns (); + int max_width = command_editor::terminal_cols (); if (free_format) {
--- a/src/pt-plot.cc +++ b/src/pt-plot.cc @@ -700,7 +700,7 @@ int n_max = 0; - file = oct_tilde_expand (data.string_value ()); + file = file_ops::tilde_expand (data.string_value ()); ifstream ftmp (file.c_str ()); @@ -850,7 +850,7 @@ string save_in_tmp_file (octave_value& t, int ndim, bool parametric) { - string name = oct_tempnam (); + string name = file_ops::tempnam (); if (! name.empty ()) {
--- a/src/sighandlers.cc +++ b/src/sighandlers.cc @@ -569,6 +569,52 @@ octave_child_list *octave_child_list::instance = 0; +bool +octave_child_list::instance_ok (void) +{ + bool retval = true; + + if (! instance) + instance = new octave_child_list (); + + if (! instance) + { + ::error ("unable to create child list object!"); + + retval = false; + } + + return retval; +} + +void +octave_child_list::insert (pid_t pid, octave_child::dead_child_handler f) +{ + if (instance_ok ()) + instance->do_insert (pid, f); +} + +void +octave_child_list::remove (pid_t pid) +{ + if (instance_ok ()) + instance->do_remove (pid); +} + +int +octave_child_list::length (void) +{ + return (instance_ok ()) ? instance->do_length () : 0; +} + +octave_child& +octave_child_list::elem (int i) +{ + static octave_child foo; + + return (instance_ok ()) ? instance->do_elem (i) : foo; +} + void octave_child_list::do_insert (pid_t pid, octave_child::dead_child_handler f) { @@ -607,18 +653,6 @@ } void -octave_child_list::insert (pid_t pid, octave_child::dead_child_handler f) -{ - if (! instance) - instance = new octave_child_list (); - - if (instance) - instance->do_insert (pid, f); - else - panic_impossible (); -} - -void octave_child_list::do_remove (pid_t pid) { // Mark the record for PID invalid. @@ -635,16 +669,23 @@ } } -void -octave_child_list::remove (pid_t pid) +int +octave_child_list::do_length (void) const +{ + return curr_len; +} + +octave_child& +octave_child_list::do_elem (int i) { - if (! instance) - instance = new octave_child_list (); + static octave_child foo; + + int n = do_length (); - if (instance) - instance->do_remove (pid); + if (i >= 0 && i < n) + return list (i); else - panic_impossible (); + return foo; } /*
--- a/src/sighandlers.h +++ b/src/sighandlers.h @@ -148,26 +148,15 @@ ~octave_child_list (void) { } + static bool instance_ok (void); + static void insert (pid_t pid, octave_child::dead_child_handler f); static void remove (pid_t pid); - static int length (void) { return instance ? instance->curr_len : 0; } - - static octave_child& elem (int i) - { - static octave_child foo; + static int length (void); - if (instance) - { - int n = length (); - - if (i >= 0 && i < n) - return instance->list (i); - } - - return foo; - } + static octave_child& elem (int i); private: @@ -180,6 +169,10 @@ void do_insert (pid_t pid, octave_child::dead_child_handler f); void do_remove (pid_t pid); + + int do_length (void) const; + + octave_child& do_elem (int i); }; #endif
--- a/src/symtab.cc +++ b/src/symtab.cc @@ -30,7 +30,7 @@ #include <cctype> -#include "oct-glob.h" +#include "glob-match.h" #include "str-vec.h" #include "error.h"
--- a/src/syscalls.cc +++ b/src/syscalls.cc @@ -44,9 +44,11 @@ #include <fcntl.h> #endif +#include "file-ops.h" +#include "file-stat.h" + #include "defun.h" #include "error.h" -#include "file-ops.h" #include "gripes.h" #include "help.h" #include "lo-utils.h" @@ -473,7 +475,7 @@ if (args.length () == 1) { - string fname = oct_tilde_expand (args(0).string_value ()); + string fname = file_ops::tilde_expand (args(0).string_value ()); if (! error_state) { @@ -526,7 +528,7 @@ string msg; - int status = oct_mkfifo (name, mode, msg); + int status = file_ops::mkfifo (name, mode, msg); retval(0) = static_cast<double> (status); @@ -633,7 +635,7 @@ if (args.length () == 1) { - string fname = oct_tilde_expand (args(0).string_value ()); + string fname = file_ops::tilde_expand (args(0).string_value ()); if (! error_state) { @@ -682,7 +684,7 @@ string msg; - int status = oct_unlink (name, msg); + int status = file_ops::unlink (name, msg); retval(0) = static_cast<double> (status);
--- a/src/sysdep.cc +++ b/src/sysdep.cc @@ -71,16 +71,11 @@ #include <sys/utsname.h> #endif -#if defined (USE_READLINE) -#include <readline/readline.h> -#include <readline/tilde.h> -#endif - -extern char *term_clrpag; -extern "C" void _rl_output_character_function (); - +#include "cmd-edit.h" +#include "file-ops.h" #include "lo-mappers.h" #include "mach-info.h" +#include "oct-env.h" #include "oct-math.h" #include "defun.h" @@ -88,7 +83,6 @@ #include "help.h" #include "input.h" #include "oct-obj.h" -#include "pathlen.h" #include "ov.h" #include "sysdep.h" #include "toplev.h" @@ -122,9 +116,7 @@ if (code == 5) warning ("hopefully recoverable malloc error: freeing wild pointer"); else - { - panic ("probably irrecoverable malloc error: code %d", code); - } + panic ("probably irrecoverable malloc error: code %d", code); } static void @@ -357,70 +349,12 @@ return c; } -string -octave_getcwd (void) -{ - string retval; - char buf[MAXPATHLEN]; - -#if defined (__EMX__) - char *tmp = _getcwd2 (buf, MAXPATHLEN); -#else - char *tmp = getcwd (buf, MAXPATHLEN); -#endif - - if (tmp) - retval = tmp; - - return retval; -} - -int -octave_chdir (const string& path) -{ -#if defined (__EMX__) - int retval = -1; - - char *tmp_path = strsave (path.c_str ()); - - if (path.length () == 2 && path[1] == ':') - { - char *upper_case_dir_name = strupr (tmp_path); - _chdrive (upper_case_dir_name[0]); - if (_getdrive () == upper_case_dir_name[0]) - retval = _chdir2 ("/"); - } - else - retval = _chdir2 (tmp_path); - - delete [] tmp_path; - - return retval; -#else - return chdir (path.c_str ()); -#endif -} - DEFUN (clc, , , "clc (): clear screen") { - octave_value_list retval; - - rl_beg_of_line (); - rl_kill_line (1); + command_editor::clear_screen (); -#if ! defined (_GO32_) - if (term_clrpag) - tputs (term_clrpag, 1, _rl_output_character_function); - else - crlf (); -#else - crlf (); -#endif - - fflush (rl_outstream); - - return retval; + return octave_value_list (); } DEFALIAS (home, clc); @@ -434,17 +368,10 @@ if (nargin == 1) { - string tstr = args(0).string_value (); - const char *name = tstr.c_str (); + string name = args(0).string_value (); if (! error_state) - { - char *value = getenv (name); - if (value) - retval = value; - else - retval = ""; - } + retval = octave_env::getenv (name); } else print_usage ("getenv"); @@ -468,7 +395,7 @@ string val = args(1).string_value (); if (! error_state) - oct_putenv (var.c_str (), val.c_str ()); + octave_env::putenv (var, val); else error ("putenv: second argument should be a string"); } @@ -612,66 +539,6 @@ || flt_fmt == oct_mach_info::ieee_big_endian); } -#if !defined (HAVE_GETHOSTNAME) && defined (HAVE_SYS_UTSNAME_H) -int -gethostname (char *name, int namelen) -{ - int i; - struct utsname ut; - - --namelen; - - uname (&ut); - i = strlen (ut.nodename) + 1; - strncpy (name, ut.nodename, i < namelen ? i : namelen); - name[namelen] = '\0'; - - return 0; -} -#endif - -// The check for error state allows us to do this: -// -// string foo = oct_tilde_expand (args(0).string_value ()); -// -// without having to use a temporary and check error_state before -// calling oct_tilde_expand. - -string -oct_tilde_expand (const string& name) -{ - string retval; - - if (! error_state) - { - char *tmp = tilde_expand (name.c_str ()); - retval = tmp; - delete [] tmp; - } - - return retval; -} - -// A vector version of the above. - -string_vector -oct_tilde_expand (const string_vector& names) -{ - string_vector retval; - - if (! error_state) - { - int n = names.length (); - - retval.resize (n); - - for (int i = 0; i < n; i++) - retval[i] = oct_tilde_expand (names[i]); - } - - return retval; -} - DEFUN (tilde_expand, args, , "tilde_expand (STRING): perform tilde expansion on STRING") { @@ -680,7 +547,7 @@ int nargin = args.length (); if (nargin == 1) - retval = oct_tilde_expand (args(0).all_strings ()); + retval = file_ops::tilde_expand (args(0).all_strings ()); else print_usage ("tilde_expand"); @@ -690,7 +557,7 @@ #if defined (__EMX__) && defined (OS2) DEFUN_TEXT (extproc, , , - "extproc : ignored by Octave") + "extproc: ignored by Octave") { return octave_value_list (); }
--- a/src/sysdep.h +++ b/src/sysdep.h @@ -26,22 +26,13 @@ #include <string> #include "lo-ieee.h" +#include "lo-sysdep.h" extern void sysdep_init (void); extern void raw_mode (int); extern int kbhit (void); -extern string octave_getcwd (void); -extern int octave_chdir (const string&); - -#if !defined (HAVE_GETHOSTNAME) && defined (HAVE_SYS_UTSNAME_H) -extern int gethostname (char *, int); -#endif - -extern string oct_tilde_expand (const string&); -extern string_vector oct_tilde_expand (const string_vector&); - #endif /*
--- a/src/toplev.cc +++ b/src/toplev.cc @@ -44,6 +44,8 @@ #include <unistd.h> #endif +#include "cmd-edit.h" +#include "file-ops.h" #include "lo-error.h" #include "lo-mappers.h" #include "str-vec.h" @@ -77,21 +79,6 @@ #include "variables.h" #include <version.h> -// argv[0] for this program. -string Vprogram_invocation_name; - -// Cleaned-up name of this program, not including path information. -string Vprogram_name; - -// Login name for user running this program. -string Vuser_name; - -// Name of the host we are running on. -string Vhost_name; - -// User's home directory. -string Vhome_directory; - // Nonzero means we print static bool Vdefault_eval_print_flag = true; @@ -103,16 +90,7 @@ // Nonzero means we are using readline. // (--no-line-editing) -#if defined (USE_READLINE) -int using_readline = 1; -#else -int using_readline = 0; -#endif - -#if defined (USE_READLINE) -// This is from readline's rltty.c: -extern "C" void rl_deprep_terminal (void); -#endif +int line_editing = 1; // Nonzero means we printed messages about reading startup files. int reading_startup_message_printed = 0; @@ -152,10 +130,10 @@ switch_to_buffer (new_buf); - unwind_protect_int (using_readline); + unwind_protect_int (line_editing); unwind_protect_int (input_from_command_line_file); - using_readline = 0; + line_editing = 0; input_from_command_line_file = 0; unwind_protect_ptr (curr_sym_tab); @@ -336,7 +314,7 @@ if (! error_state) { - file = oct_tilde_expand (file); + file = file_ops::tilde_expand (file); parse_and_execute (file, false, "source"); @@ -357,13 +335,12 @@ void clean_up_and_exit (int retval) { -#if defined (USE_READLINE) - rl_deprep_terminal (); -#else + command_editor::restore_terminal_state (); + + // XXX FIXME XXX -- is this needed? Can it cause any trouble? raw_mode (0); -#endif - octave_command_history.clean_up_and_save (); + command_history::clean_up_and_save (); close_plot_stream ();
--- a/src/toplev.h +++ b/src/toplev.h @@ -52,30 +52,12 @@ extern void do_octave_atexit (void); -// argv[0] for this program. -extern string Vprogram_invocation_name; - -// Cleaned-up name of this program, not including path information. -extern string Vprogram_name; - -// Login name for user running this program. -extern string Vuser_name; - -// Name of the host we are running on. -extern string Vhost_name; - -// Home directory for the current user. -extern string Vhome_directory; - // Nonzero means we are using readline. -extern int using_readline; +extern int line_editing; // Nonzero means we printed messages about reading startup files. extern int reading_startup_message_printed; -// Command number, counting from the beginning of this session. -extern int current_command_number; - // Nonzero means we are exiting via the builtin exit or quit functions. extern int quitting_gracefully;
--- a/src/utils.cc +++ b/src/utils.cc @@ -57,8 +57,9 @@ #include "SLStack.h" -#include "file-ops.h" +#include "file-stat.h" #include "oct-cmplx.h" +#include "oct-env.h" #include "str-vec.h" #include <defaults.h> @@ -82,20 +83,6 @@ // Top level context (?) extern jmp_buf toplevel; -// Save a string. - -char * -strsave (const char *s) -{ - if (! s) - return 0; - - int len = strlen (s); - char *tmp = new char [len+1]; - tmp = strcpy (tmp, s); - return tmp; -} - // Return to the main command loop in octave.cc. extern "C" void @@ -245,7 +232,7 @@ { dir_path p (path); - return make_absolute (p.find (name), Vcurrent_directory); + return octave_env::make_absolute (p.find (name), octave_env::getcwd ()); } DEFUN (file_in_path, args, , @@ -283,9 +270,6 @@ if (! suffix.empty ()) nm.append (suffix); - if (Vcurrent_directory.empty ()) - get_working_directory ("file_in_path"); - return search_path_for_file (Vload_path, nm); } @@ -403,91 +387,6 @@ return retval; } -// This function was adapted from xputenv from Karl Berry's kpathsearch -// library. - -void -oct_putenv (const char *var_name, const char *value) -{ - static const char **saved_env_items = 0; - static unsigned saved_len; - char *old_item = 0; - - int new_len = strlen (var_name) + strlen (value) + 2; - - char *new_item = new char [new_len]; - - sprintf (new_item, "%s=%s", var_name, value); - -#ifndef SMART_PUTENV - - // Check if we have saved anything yet. - - if (! saved_env_items) - { - saved_env_items = new const char * [1]; - saved_env_items[0] = var_name; - saved_len = 1; - } - else - { - // Check if we've assigned VAR_NAME before. - - unsigned len = strlen (var_name); - - for (unsigned i = 0; i < saved_len && ! old_item; i++) - { - if (strcmp (saved_env_items[i], var_name) == 0) - { - old_item = getenv (var_name); - - assert (old_item); - - // Back up to the `NAME=' in the environment before the - // value that getenv returns. - - old_item -= (len + 1); - } - } - - if (! old_item) - { - // If we haven't seen VAR_NAME before, save it. Assume it - // is in safe storage. - - saved_len++; - - const char **tmp = new const char * [saved_len]; - - for (unsigned i = 0; i < saved_len - 1; i++) - tmp[i] = saved_env_items[i]; - - tmp[saved_len - 1] = var_name; - - delete [] saved_env_items; - - saved_env_items = tmp; - } - } - -#endif - - // As far as I can see there's no way to distinguish between the - // various errors; putenv doesn't have errno values. - - if (putenv (new_item) < 0) - error ("putenv (%s) failed", new_item); - -#ifndef SMART_PUTENV - - // Can't free `new_item' because its contained value is now in - // `environ', but we can free `old_item', since it's been replaced. - - delete [] old_item; - -#endif -} - static void warn_old_style_preference (bool val, const string& sval) {
--- a/src/utils.h +++ b/src/utils.h @@ -33,8 +33,6 @@ class octave_value_list; class string_vector; -extern char *strsave (const char *); - extern string search_path_for_file (const string&, const string&); extern string file_in_path (const string&, const string&); extern string fcn_file_in_path (const string&); @@ -56,8 +54,6 @@ extern string undo_string_escapes (const string& s); -extern void oct_putenv (const char *, const char *); - extern int check_preference (const string& var); #endif
--- a/src/variables.cc +++ b/src/variables.cc @@ -41,13 +41,13 @@ #include <unistd.h> #endif -#if defined (USE_READLINE) -#include <readline/readline.h> -#endif - +#include "cmd-edit.h" +#include "cmd-hist.h" #include "file-ops.h" +#include "file-stat.h" #include "lo-mappers.h" -#include "oct-glob.h" +#include "oct-env.h" +#include "glob-match.h" #include "str-vec.h" #include <defaults.h> @@ -55,27 +55,23 @@ #include "dirfns.h" #include "dynamic-ld.h" #include "error.h" -#include "file-io.h" #include "fn-cache.h" #include "gripes.h" #include "help.h" #include "input.h" #include "lex.h" -#include "load-save.h" +#include "sysdep.h" #include "oct-hist.h" -#include "toplev.h" +#include "oct-map.h" +#include "oct-mapper.h" +#include "oct-obj.h" +#include "oct-sym.h" +#include "ov.h" #include "pager.h" #include "parse.h" -#include "symtab.h" -#include "sysdep.h" -#include "oct-sym.h" -#include "oct-builtin.h" -#include "oct-mapper.h" -#include "oct-usr-fcn.h" -#include "oct-obj.h" #include "pt-id.h" #include "pt-indir.h" -#include "pr-output.h" +#include "symtab.h" #include "toplev.h" #include "unwind-prot.h" #include "utils.h" @@ -586,13 +582,12 @@ // Is there a corresponding function file that is newer than the // symbol definition? -static int +static bool symbol_out_of_date (symbol_record *sr) { - if (Vignore_function_time_stamp == 2) - return 0; + bool retval = false; - if (sr) + if (Vignore_function_time_stamp != 2 && sr) { octave_symbol *ans = sr->def (); if (ans) @@ -606,19 +601,22 @@ string fname = fcn_file_in_path (ff); - int status = is_newer (fname, tp); + int status = file_stat::is_newer (fname, tp); if (status > 0) - return 1; + retval = true; } } } - return 0; + + return retval; } -static int +static bool looks_like_octave_copyright (const string& s) { + bool retval = false; + string t = s.substr (0, 15); if (t == " Copyright (C) ") @@ -637,11 +635,12 @@ if (t == " This file is part of Octave." || t == " This program is free softwar") - return 1; + retval = true; } } } - return 0; + + return retval; } // Eat whitespace and comments from FFILE, returning the text of the @@ -782,7 +781,7 @@ static void restore_command_history (void *) { - octave_command_history.ignore_entries (! Vsaving_history); + command_history::ignore_entries (! Vsaving_history); } static void @@ -792,6 +791,12 @@ fclose (static_cast<FILE *> (f)); } +static void +restore_input_stream (void *f) +{ + command_editor::set_input_stream (static_cast<FILE *> (f)); +} + static int parse_fcn_file (bool exec_script, const string& ff) { @@ -803,15 +808,18 @@ int old_reading_fcn_file_state = reading_fcn_file; - unwind_protect_ptr (rl_instream); + FILE *in_stream = command_editor::get_input_stream (); + + add_unwind_protect (restore_input_stream, in_stream); + unwind_protect_ptr (ff_instream); - unwind_protect_int (using_readline); + unwind_protect_int (line_editing); unwind_protect_int (input_line_number); unwind_protect_int (current_input_column); unwind_protect_int (reading_fcn_file); - using_readline = 0; + line_editing = 0; reading_fcn_file = 1; input_line_number = 0; current_input_column = 1; @@ -828,9 +836,9 @@ if (is_function_file (ffile)) { // XXX FIXME XXX -- we shouldn't need both the - // octave_command_history object and the + // command_history object and the // Vsaving_history variable... - octave_command_history.ignore_entries (); + command_history::ignore_entries (); add_unwind_protect (restore_command_history, 0); @@ -877,9 +885,9 @@ reading_fcn_file = old_reading_fcn_file_state; // XXX FIXME XXX -- we shouldn't need both the - // octave_command_history object and the + // command_history object and the // Vsaving_history variable... - octave_command_history.ignore_entries (); + command_history::ignore_entries (); add_unwind_protect (restore_command_history, 0); @@ -1728,7 +1736,7 @@ if (ival >= 0 && ival == val) { Vhistory_size = ival; - octave_command_history.set_size (ival); + command_history::set_size (ival); return 0; } } @@ -1751,7 +1759,7 @@ else { Vhistory_file = s; - octave_command_history.set_file (oct_tilde_expand (s)); + command_history::set_file (file_ops::tilde_expand (s)); } return status; @@ -1782,7 +1790,7 @@ { Vsaving_history = check_preference ("saving_history"); - octave_command_history.ignore_entries (! Vsaving_history); + command_history::ignore_entries (! Vsaving_history); return 0; } @@ -1822,11 +1830,12 @@ "don't check to see if function files have changed since they were\n\ last compiled. Possible values are \"system\" and \"all\""); - DEFCONST (program_invocation_name, Vprogram_invocation_name, 0, 0, + DEFCONST (program_invocation_name, + octave_env::get_program_invocation_name (), 0, 0, "the full name of the current program or script, including the\n\ directory specification"); - DEFCONST (program_name, Vprogram_name, 0, 0, + DEFCONST (program_name, octave_env::get_program_name (), 0, 0, "the name of the current program or script"); DEFVAR (saving_history, 1.0, 0, saving_history,