Mercurial > hg > octave-nkf
changeset 3325:2efa28a91e7a
[project @ 1999-10-29 21:39:20 by jwe]
line wrap: on
line diff
--- a/libcruft/ChangeLog +++ b/libcruft/ChangeLog @@ -1,3 +1,10 @@ +1999-10-29 John W. Eaton <jwe@bevo.che.wisc.edu> + + * misc/lo-error.cc (current_liboctave_warning_handler): Define here. + (set_liboctave_warning_handler): New function. + (liboctave_warning): Ditto. + * misc/lo-error.h: Provide declararations for them here. + 1999-10-19 John W. Eaton <jwe@bevo.che.wisc.edu> * Makefile.in (dist): Use `$(MAKE) -C dir' instead of `cd dir;
--- a/libcruft/Makerules.in +++ b/libcruft/Makerules.in @@ -14,13 +14,17 @@ DISTFILES = Makefile.in $(SOURCES) $(SPECIAL) -CRUFT_FSRC = $(wildcard $(srcdir)/*.f) -CRUFT_BASE = $(notdir $(CRUFT_FSRC)) -CRUFT_OBJ = $(patsubst %.f, %.o, $(CRUFT_BASE)) +CRUFT_FSRC = $(wildcard $(srcdir)/*.f) \ + $(wildcard $(srcdir)/*.c) \ + $(wildcard $(srcdir)/*.cc) +CRUFT_BASE = $(basename $(notdir $(CRUFT_SRC)) ) +CRUFT_OBJ = $(addsuffix .o, $(CRUFT_BASE) ) ifeq ($(SHARED_LIBS), true) ifdef FPICFLAG CRUFT_PICOBJ := $(addprefix pic/, $(CRUFT_OBJ)) + else + CRUFT_PICOBJ := $(CRUFT_OBJ) endif endif
--- a/libcruft/misc/lo-error.c +++ b/libcruft/misc/lo-error.c @@ -34,7 +34,12 @@ symbol errors when creating shared versions of libcruft. */ /* Pointer to the current error handling function. */ -liboctave_error_handler current_liboctave_error_handler = liboctave_fatal; +liboctave_error_handler current_liboctave_error_handler + = liboctave_fatal; + +/* Pointer to the current warning handler. */ +liboctave_warning_handler current_liboctave_warning_handler + = liboctave_warning; static void verror (const char *name, const char *fmt, va_list args) @@ -57,6 +62,15 @@ } void +set_liboctave_warning_handler (liboctave_warning_handler f) +{ + if (f) + current_liboctave_warning_handler = f; + else + current_liboctave_warning_handler = liboctave_warning; +} + +void liboctave_fatal (const char *fmt, ...) { va_list args; @@ -67,6 +81,15 @@ exit (1); } +void +liboctave_warning (const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + verror ("warning", fmt, args); + va_end (args); +} + /* ;;; Local Variables: *** ;;; mode: C ***
--- a/libcruft/misc/lo-error.h +++ b/libcruft/misc/lo-error.h @@ -29,14 +29,22 @@ extern void liboctave_fatal (const char *fmt, ...) GCC_ATTR_NORETURN; +extern void liboctave_warning (const char *fmt, ...); + typedef void (*liboctave_error_handler) (const char *, ...); -/* Would be nice to make this private, but we want to share it among - all the liboctave classes. */ +typedef void (*liboctave_warning_handler) (const char *, ...); + +/* Would be nice to make these pointers private, but we want to share + them among all the liboctave classes. */ extern liboctave_error_handler current_liboctave_error_handler; +extern liboctave_warning_handler current_liboctave_warning_handler; + extern void set_liboctave_error_handler (liboctave_error_handler f); +extern void set_liboctave_warning_handler (liboctave_warning_handler f); + #ifdef __cplusplus } #endif
--- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,8 @@ +1999-10-29 John W. Eaton <jwe@bevo.che.wisc.edu> + + * oct-shlib.cc, oct-shlib.h: New files. + * Makefile.in (INCLUDES, SOURCES): Add them to the lists. + 1999-10-26 John W. Eaton <jwe@bevo.che.wisc.edu> * CRowVector.cc (linspace): Allow npoints == 1 if x1 == x2.
--- a/liboctave/Makefile.in +++ b/liboctave/Makefile.in @@ -47,8 +47,8 @@ dir-ops.h file-ops.h file-stat.h getopt.h glob-match.h \ idx-vector.h lo-ieee.h lo-mappers.h lo-specfun.h lo-sysdep.h \ lo-utils.h mach-info.h oct-alloc.h oct-cmplx.h oct-env.h \ - oct-group.h oct-passwd.h oct-syscalls.h oct-time.h pathlen.h \ - pathsearch.h prog-args.h statdefs.h str-vec.h sun-utils.h \ + oct-group.h oct-passwd.h oct-shlib.h oct-syscalls.h oct-time.h \ + pathlen.h pathsearch.h prog-args.h statdefs.h str-vec.h sun-utils.h \ sysdir.h systime.h syswait.h \ $(MATRIX_INC) \ $(MX_OP_INC) @@ -80,7 +80,7 @@ file-stat.cc filemode.c getopt.c getopt1.c glob-match.cc \ idx-vector.cc lo-ieee.cc lo-mappers.cc lo-specfun.cc \ lo-sysdep.cc lo-utils.cc mach-info.cc mkdir.c oct-alloc.cc \ - oct-env.cc oct-group.cc oct-passwd.cc oct-syscalls.cc \ + oct-env.cc oct-group.cc oct-passwd.cc oct-shlib.cc oct-syscalls.cc \ oct-time.cc pathsearch.cc prog-args.cc rename.c rmdir.c \ strftime.c str-vec.cc tempname.c tempnam.c \ $(TEMPLATE_SRC) \
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,72 @@ +1999-10-29 John W. Eaton <jwe@bevo.che.wisc.edu> + + * defun-dld.h (INSTALL_DLD_FCNS, INSTALL_DLD_FCN): Delete definitions. + * DLD-FUNCTIONS/dassl.cc: Don't use INSTALL_DLD_FCN or + INSTALL_DLD_FCNS macros. They are not necessary with the new code + in dynamic-ld.cc. + * DLD-FUNCTIONS/lsode.cc: Ditto. + * DLD-FUNCTIONS/fsolve.cc: Ditto. + * DLD-FUNCTIONS/quad.cc: Ditto. + * DLD-FUNCTIONS/time.cc: Ditto. + * DLD-FUNCTIONS/besselj.cc: Ditto. + * DLD-FUNCTIONS/getgrent.cc: Ditto. + * DLD-FUNCTIONS/getpwent.cc: Ditto. + * DLD-FUNCTIONS/inv.cc: Ditto. + * DLD-FUNCTIONS/log.cc: Ditto. + * DLD-FUNCTIONS/minmax.cc: Ditto. + * DLD-FUNCTIONS/rand.cc: Ditto. + + * dynamic-ld.cc, dynamic-ld.h: Major rewrite to allow reloading of + dynamically linked functions. + + * symtab.cc (symbol_record::replace_all_defs): Don't allow top + definition to be NULL. + (symbol_table::clear): Allow dynamically linked functions to be + cleared. + + * symtab.h (TYPE): New enum value, DLD_FUCTION. + (symbol_type): Now 8 bits wide. + (SYMTAB_ALL_TYPES): Include DLD_FUNCTION. + (symbol_record::symbol_def::is_function): Also recognize dld functions. + (symbol_record::symbol_def::is_dld_function): New function. + (symbol_record::is_dld_function): Ditto. + + * defun.cc (install_dld_function): New function. + * defun-int.h: Provide declaration here. + (octave_dld_fcn_installer): New typedef. + (DEFINE_FUN_INSTALLER_FUN): Installer function now takes an + oct_shlib object as an arg. Allow installation of a function to + happen more than once. + + * octave.cc (initialize_error_handlers): Call + set_liboctave_warning_handler here too. + + * ov-builtin.h (is_builtin_function): Return true. + Data member is now protected, not private. + + * ov-fcn.h (is_dynamically_loaded_function): New predicate. + (unload): New function. + Data members are now protected, not private. + + * ov.h (is_builtin_function, is_dld_function): New predicates. + * ov-base.h (is_builtin_function, is_dld_function): Ditto. + + * parse.y (Vwarn_reload_forces_clear): New static flag. + (warn_reload_forces_clear): New function. + (symbols_of_parse): DEFVAR warn_reload_forces_clear. + + * variables.cc (Fclear): Look for dld functions too. + + * ov-dld-fcn.cc, src/ov-dld-fcn.h: New files. + * Makefile.in (OV_INCLUDES, OV_SRC): Add them to the lists. + + * Makefile.in (DEFVAR_PATTERN): Also match DEFCONSTX. + 1999-10-26 John W. Eaton <jwe@bevo.che.wisc.edu> + * DLList.h, DLList.cc: New files. + * Makefile.in (INCLUDES, DIST_SRC): Add them to the lists. + * DLD-FUNCTIONS/lsode.cc (Flsode): Be sure to call unwind_protect::run_frame before returning. * DLD-FUNCTIONS/quad.cc (Fquad): Likewise.
--- a/src/DLD-FUNCTIONS/besselj.cc +++ b/src/DLD-FUNCTIONS/besselj.cc @@ -511,13 +511,6 @@ return retval; } -INSTALL_DLD_FCNS (INSTALL_DLD_FCN (besselj); - INSTALL_DLD_FCN (bessely); - INSTALL_DLD_FCN (besseli); - INSTALL_DLD_FCN (besselk); - INSTALL_DLD_FCN (besselh); - INSTALL_DLD_FCN (airy);) - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/DLD-FUNCTIONS/dassl.cc +++ b/src/DLD-FUNCTIONS/dassl.cc @@ -391,9 +391,6 @@ return retval; } -INSTALL_DLD_FCNS (INSTALL_DLD_FCN (dassl); - INSTALL_DLD_FCN (dassl_options);) - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/DLD-FUNCTIONS/fsolve.cc +++ b/src/DLD-FUNCTIONS/fsolve.cc @@ -362,9 +362,6 @@ return retval; } -INSTALL_DLD_FCNS (INSTALL_DLD_FCN (fsolve); - INSTALL_DLD_FCN (fsolve_options);) - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/DLD-FUNCTIONS/getgrent.cc +++ b/src/DLD-FUNCTIONS/getgrent.cc @@ -216,12 +216,6 @@ return retval; } -INSTALL_DLD_FCNS (INSTALL_DLD_FCN (getgrent); - INSTALL_DLD_FCN (getgrgid); - INSTALL_DLD_FCN (getgrnam); - INSTALL_DLD_FCN (setgrent); - INSTALL_DLD_FCN (endgrent);) - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/DLD-FUNCTIONS/getpwent.cc +++ b/src/DLD-FUNCTIONS/getpwent.cc @@ -220,12 +220,6 @@ return retval; } -INSTALL_DLD_FCNS (INSTALL_DLD_FCN (getpwent); - INSTALL_DLD_FCN (getpwuid); - INSTALL_DLD_FCN (getpwnam); - INSTALL_DLD_FCN (setpwent); - INSTALL_DLD_FCN (endpwent);) - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/DLD-FUNCTIONS/inv.cc +++ b/src/DLD-FUNCTIONS/inv.cc @@ -111,9 +111,6 @@ return Finv (args, nargout); } -INSTALL_DLD_FCNS (INSTALL_DLD_FCN (inv); - INSTALL_DLD_FCN (inverse);) - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/DLD-FUNCTIONS/log.cc +++ b/src/DLD-FUNCTIONS/log.cc @@ -259,9 +259,6 @@ return retval; } -INSTALL_DLD_FCNS (INSTALL_DLD_FCN (logm); - INSTALL_DLD_FCN (sqrtm);) - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/DLD-FUNCTIONS/lsode.cc +++ b/src/DLD-FUNCTIONS/lsode.cc @@ -492,9 +492,6 @@ return retval; } -INSTALL_DLD_FCNS (INSTALL_DLD_FCN (lsode); - INSTALL_DLD_FCN (lsode_options);) - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/DLD-FUNCTIONS/minmax.cc +++ b/src/DLD-FUNCTIONS/minmax.cc @@ -701,9 +701,6 @@ return retval; } -INSTALL_DLD_FCNS (INSTALL_DLD_FCN (min); - INSTALL_DLD_FCN (max);) - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/DLD-FUNCTIONS/quad.cc +++ b/src/DLD-FUNCTIONS/quad.cc @@ -419,9 +419,6 @@ return retval; } -INSTALL_DLD_FCNS (INSTALL_DLD_FCN (quad); - INSTALL_DLD_FCN (quad_options);) - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/DLD-FUNCTIONS/rand.cc +++ b/src/DLD-FUNCTIONS/rand.cc @@ -408,9 +408,6 @@ return retval; } -INSTALL_DLD_FCNS (INSTALL_DLD_FCN (rand); - INSTALL_DLD_FCN (randn);) - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/DLD-FUNCTIONS/time.cc +++ b/src/DLD-FUNCTIONS/time.cc @@ -396,12 +396,6 @@ return retval; } -INSTALL_DLD_FCNS (INSTALL_DLD_FCN (time); - INSTALL_DLD_FCN (gmtime); - INSTALL_DLD_FCN (localtime); - INSTALL_DLD_FCN (mktime); - INSTALL_DLD_FCN (strftime);) - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/Makefile.in +++ b/src/Makefile.in @@ -74,7 +74,8 @@ ov-struct.h ov-scalar.h ov-range.h ov-complex.h ov-va-args.h \ ov-colon.h ov-base.h ov-base-mat.h ov-base-scalar.h \ ov-str-mat.h ov-bool-mat.h ov-bool.h ov-file.h ov.h \ - ov-fcn.h ov-builtin.h ov-mapper.h ov-usr-fcn.h ov-typeinfo.h + ov-fcn.h ov-builtin.h ov-dld-fcn.h ov-mapper.h ov-usr-fcn.h \ + ov-typeinfo.h PT_INCLUDES := pt.h pt-all.h pt-arg-list.h pt-assign.h pt-binop.h \ pt-check.h pt-cmd.h pt-colon.h pt-const.h pt-decl.h \ @@ -82,7 +83,7 @@ pt-jump.h pt-loop.h pt-mat.h pt-misc.h pt-plot.h \ pt-pr-code.h pt-select.h pt-stmt.h pt-unop.h pt-walk.h -INCLUDES := BaseSLList.h Map.h Pix.h SLList.h SLStack.h Stack.h \ +INCLUDES := BaseSLList.h DLList.h Map.h Pix.h SLList.h SLStack.h Stack.h \ defun-dld.h defun-int.h defun.h dirfns.h dynamic-ld.h error.h \ file-io.h fn-cache.h gripes.h help.h input.h lex.h load-save.h \ oct-fstrm.h oct-hist.h oct-iostrm.h oct-map.h oct-obj.h \ @@ -114,7 +115,8 @@ ov-list.cc ov-re-mat.cc ov-cx-mat.cc ov-range.cc ov-scalar.cc \ ov-complex.cc ov-str-mat.cc ov-struct.cc ov-va-args.cc \ ov-colon.cc ov-bool-mat.cc ov-bool.cc ov-file.cc ov.cc ov-fcn.cc \ - ov-builtin.cc ov-mapper.cc ov-usr-fcn.cc ov-typeinfo.cc + ov-builtin.cc ov-dld-fcn.cc ov-mapper.cc ov-usr-fcn.cc \ + ov-typeinfo.cc PT_SRC := pt.cc pt-arg-list.cc pt-assign.cc pt-binop.cc pt-check.cc \ pt-cmd.cc pt-colon.cc pt-const.cc pt-decl.cc pt-except.cc \ @@ -122,7 +124,7 @@ pt-loop.cc pt-mat.cc pt-misc.cc pt-plot.cc pt-pr-code.cc \ pt-select.cc pt-stmt.cc pt-unop.cc -DIST_SRC := BaseSLList.cc Map.cc SLList.cc SLStack.cc Stack.cc \ +DIST_SRC := BaseSLList.cc DLList.cc Map.cc SLList.cc SLStack.cc Stack.cc \ cutils.c data.cc defaults.cc defun.cc dirfns.cc dynamic-ld.cc \ error.cc file-io.cc fn-cache.cc gripes.cc help.cc input.cc \ lex.l load-save.cc mappers.cc matherr.c oct-fstrm.cc \ @@ -172,7 +174,7 @@ DEF_1 := $(patsubst %.l, %.df, $(DEF_2)) DEF_FILES := $(patsubst %.cc, %.df, $(DEF_1)) -DEFVAR_PATTERN = "^[ \t]*DEF(VAR|CONST)[ \t]*\\(" +DEFVAR_PATTERN = "^[ \t]*DEF(VAR|CONS(T|TX))[ \t]*\\(" VAR_5 := $(SOURCES) $(DLD_SRC) VAR_4 := $(addprefix $(srcdir)/, $(VAR_5))
--- a/src/defun-dld.h +++ b/src/defun-dld.h @@ -55,26 +55,6 @@ DEFINE_FUN_INSTALLER_FUN (name, doc) \ DECLARE_FUN (name, args_name, nargout_name) -#if (defined (OCTAVE_LITE) && defined (WITH_DYNAMIC_LINKING)) - -#define INSTALL_DLD_FCNS(body) \ - bool \ - FSoctave_install_dld_functions (void) \ - { \ - body \ - return true; \ - } - -#else - -#define INSTALL_DLD_FCNS(body) - -#endif - -#define INSTALL_DLD_FCN(name) \ - if (! FS ## name ()) \ - return false - #endif #endif
--- a/src/defun-int.h +++ b/src/defun-int.h @@ -26,6 +26,7 @@ #include <string> #include "ov-builtin.h" +#include "ov-dld-fcn.h" #include "ov-mapper.h" #include "symtab.h" #include "version.h" @@ -54,29 +55,32 @@ bool p, const string& h); extern void -alias_builtin (const string& alias, const string& name); - -// Define the code that will be used to insert the new function into -// the symbol table. +install_dld_function (octave_dld_function::fcn f, const string& name, + const octave_shlib& shl, + const string& doc, bool is_text_fcn = false); -#define DEFINE_FUN_INSTALLER_FUN(name, doc) \ - bool \ - FS ## name (void) \ - { \ - static bool installed = false; \ - if (! installed) \ - { \ - check_version (OCTAVE_VERSION, #name); \ - install_builtin_function (F ## name, #name, doc); \ - installed = true; \ - } \ - return installed; \ - } +extern void +alias_builtin (const string& alias, const string& name); #define DECLARE_FUN(name, args_name, nargout_name) \ octave_value_list \ F ## name (const octave_value_list& args_name, int nargout_name) +// Define the code that will be used to insert the new function into +// the symbol table. We look for this name instead of the actual +// function so that we can easily install the doc string too. + +typedef bool (*octave_dld_fcn_installer) (const octave_shlib&); + +#define DEFINE_FUN_INSTALLER_FUN(name, doc) \ + bool \ + FS ## name (const octave_shlib& shl) \ + { \ + check_version (OCTAVE_VERSION, #name); \ + install_dld_function (F ## name, #name, shl, doc); \ + return error_state ? false : true; \ + } + // MAKE_BUILTINS is defined to extract function names and related // information and create the *.df files that are eventually used to // create the builtins.cc file.
--- a/src/defun.cc +++ b/src/defun.cc @@ -26,11 +26,15 @@ #include <string> +#include <iostream.h> + #include "defun-int.h" +#include "dynamic-ld.h" #include "error.h" #include "help.h" #include "ov.h" #include "ov-builtin.h" +#include "ov-dld-fcn.h" #include "ov-mapper.h" #include "pager.h" #include "symtab.h" @@ -118,6 +122,25 @@ } void +install_dld_function (octave_dld_function::fcn f, const string& name, + const octave_shlib& shl, + const string& doc, bool is_text_fcn) +{ + symbol_record *sym_rec = global_sym_tab->lookup (name, true); + + unsigned int t = symbol_record::DLD_FUNCTION; + + if (is_text_fcn) + t |= symbol_record::TEXT_FUNCTION; + + sym_rec->unprotect (); + sym_rec->define (new octave_dld_function (f, shl, name, doc), t); + sym_rec->document (doc); + sym_rec->make_eternal (); + sym_rec->protect (); +} + +void alias_builtin (const string& alias, const string& name) { symbol_record *sr_name = global_sym_tab->lookup (name);
--- a/src/dynamic-ld.cc +++ b/src/dynamic-ld.cc @@ -24,214 +24,124 @@ #include <config.h> #endif -#if defined (WITH_SHL) -#include <cerrno> -#include <cstring> -#endif - -#include <strstream.h> +#include "oct-time.h" +#include "file-stat.h" -extern "C" -{ -#if defined (WITH_DL) -#if defined (HAVE_DLFCN_H) -#include <dlfcn.h> -#else -extern void *dlopen (const char *, int); -extern const char *dlerror (void); -extern void *dlsym (void *, const char *); -extern int dlclose (void *); -#endif -#ifndef RTLD_LAZY -#define RTLD_LAZY 1 -#endif -#elif defined (WITH_SHL) -#include <dl.h> -#endif -} +#include "DLList.h" #include <defaults.h> -#include "dirfns.h" + +#include "defun.h" #include "dynamic-ld.h" -#include "error.h" -#include "toplev.h" -#include "pathsearch.h" -#include "oct-obj.h" -#include "ov-builtin.h" -#include "ov.h" +#include "parse.h" +#include "unwind-prot.h" #include "utils.h" #include "variables.h" -#if defined (WITH_DL) +// TRUE means we print a warning if reloading a .oct file forces other +// functions to be cleared. +static bool Vwarn_reload_forces_clear; + +template class DLNode<octave_shlib>; +template class DLList<octave_shlib>; class -octave_dlopen_dynamic_loader : public octave_dynamic_loader +octave_shlib_list { public: - octave_dlopen_dynamic_loader (void) - : octave_dynamic_loader () { } + static void append (const octave_shlib& shl); - ~octave_dlopen_dynamic_loader (void) { } + static void remove (octave_shlib& shl); + + static void *search (const string& fcn_name, octave_shlib& shl, + octave_shlib::name_mangler mangler = 0); private: - octave_dynamic_loader::builtin_fcn_installer - resolve_reference (const string& mangled_name, const string& file); + octave_shlib_list (void) { } + + ~octave_shlib_list (void) { } + + void do_append (const octave_shlib& shl); + + void do_remove (octave_shlib& shl); + + void *do_search (const string& fcn_name, octave_shlib& shl, + octave_shlib::name_mangler mangler = 0); + + static octave_shlib_list *instance; + + static bool instance_ok (void); + + // List of libraries we have loaded. + DLList<octave_shlib> lib_list; // No copying! - octave_dlopen_dynamic_loader (const octave_dlopen_dynamic_loader&); + octave_shlib_list (const octave_shlib_list&); - octave_dlopen_dynamic_loader& - operator = (const octave_dlopen_dynamic_loader&); + octave_shlib_list& operator = (const octave_shlib_list&); }; -octave_dynamic_loader::builtin_fcn_installer -octave_dlopen_dynamic_loader::resolve_reference (const string& name, - const string& file) -{ - octave_dynamic_loader::builtin_fcn_installer retval = 0; - - // Dynamic linking with dlopen/dlsym doesn't require specification - // of the libraries at runtime. Instead, they are specified when - // the .oct file is created. - - void *handle = dlopen (file.c_str (), RTLD_LAZY); - - string mangled_name = mangle_name (name); - - const char *nm = mangled_name.c_str (); - - if (handle) - { - // Try the installer function first. - - string tmp_name = mangle_name ("octave_install_dld_functions"); - - const char *tmp_nm = tmp_name.c_str (); - - void *tmp = dlsym (handle, tmp_nm); +octave_shlib_list *octave_shlib_list::instance = 0; - retval = X_CAST (octave_dynamic_loader::builtin_fcn_installer, - tmp); - if (! retval) - { - tmp = dlsym (handle, nm); - - retval = X_CAST (octave_dynamic_loader::builtin_fcn_installer, tmp); - - if (! retval) - { - const char *errmsg = dlerror (); - - if (errmsg) - error("%s: `%s'", nm, errmsg); - else - error("unable to link function `%s'", nm); - - dlclose (handle); - } - } - } - else - error ("%s: %s `%s'", dlerror (), file.c_str (), nm); - - return retval; +void +octave_shlib_list::do_append (const octave_shlib& shl) +{ + lib_list.append (shl); } -#elif defined (WITH_SHL) - -class -octave_shl_load_dynamic_loader : public octave_dynamic_loader +void +octave_shlib_list::do_remove (octave_shlib& shl) { -public: - - octave_shl_load_dynamic_loader (void) - : octave_dynamic_loader () { } - - ~octave_shl_load_dynamic_loader (void) { } - -private: - - octave_dynamic_loader::builtin_fcn_installer - resolve_reference (const string& mangled_name, const string& file); - - // No copying! - - octave_shl_load_dynamic_loader (const octave_shl_load_dynamic_loader&); - - octave_shl_load_dynamic_loader& - operator = (const octave_shl_load_dynamic_loader&); -}; - -octave_dynamic_loader::builtin_fcn_installer -octave_shl_load_dynamic_loader::resolve_reference (const string& name, - const string& file) -{ - octave_dynamic_loader::builtin_fcn_installer retval = 0; - - // Dynamic linking with shl_load/shl_findsym doesn't require - // specification of the libraries at runtime. Instead, they are - // specified when the .oct file is created. + for (Pix p = lib_list.first (); p != 0; lib_list.next (p)) + { + if (lib_list(p) == shl) + { + shl.close (); - shl_t handle = shl_load (file.c_str (), BIND_DEFERRED, 0L); - - string mangled_name = mangle_name (name); - - const char *nm = mangled_name.c_str (); - - if (handle) - { - // Try the installer function first. - - string tmp_name = mangle_name ("octave_install_dld_functions"); - - const char *tmp_nm = tmp_name.c_str (); - - // Don't use TYPE_PROCEDURE here. The man page says that future - // versions of HP-UX may not support it. + lib_list.del (p); - int status = shl_findsym (&handle, tmp_nm, TYPE_UNDEFINED, &retval); - - if (status < 0) - { - status = shl_findsym (&handle, nm, TYPE_UNDEFINED, &retval); - - if (status < 0) - { - const char *errmsg = strerror (errno); - - if (errmsg) - error("%s: `%s'", nm, errmsg); - else - error("unable to link function `%s'", nm); - - retval = 0; - } + break; } } - else - error ("%s: %s `%s'", strerror (errno), file.c_str (), nm); - - return retval; } -#endif +void * +octave_shlib_list::do_search (const string& fcn_name, octave_shlib& shl, + octave_shlib::name_mangler mangler) +{ + void *function = 0; + + shl = octave_shlib (); -octave_dynamic_loader *octave_dynamic_loader::instance = 0; + for (Pix p = lib_list.first (); p != 0; lib_list.next (p)) + { + function = lib_list(p).search (fcn_name, mangler); + + if (function) + { + shl = lib_list(p); + + break; + } + } + + return function; +} bool -octave_dynamic_loader::instance_ok (void) +octave_shlib_list::instance_ok (void) { bool retval = true; if (! instance) - make_dynamic_loader (); + instance = new octave_shlib_list (); if (! instance) { - error ("unable to create command history object!"); + ::error ("unable to create shared library list object!"); retval = false; } @@ -240,43 +150,162 @@ } void -octave_dynamic_loader::make_dynamic_loader (void) +octave_shlib_list::append (const octave_shlib& shl) +{ + if (instance_ok ()) + instance->do_append (shl); +} + +void +octave_shlib_list::remove (octave_shlib& shl) { -#if defined (WITH_DL) - instance = new octave_dlopen_dynamic_loader (); -#elif defined (WITH_SHL) - instance = new octave_shl_load_dynamic_loader (); -#else - instance = new octave_dynamic_loader (); -#endif + if (instance_ok ()) + instance->do_remove (shl); } +void * +octave_shlib_list::search (const string& fcn_name, octave_shlib& shl, + octave_shlib::name_mangler mangler) +{ + return (instance_ok ()) ? instance->do_search (fcn_name, shl, mangler) : 0; +} + +octave_dynamic_loader *octave_dynamic_loader::instance = 0; + +bool octave_dynamic_loader::doing_load = false; + bool -octave_dynamic_loader::load_fcn_from_dot_oct_file (const string& fcn_name) +octave_dynamic_loader::instance_ok (void) { - if (! instance_ok ()) - make_dynamic_loader (); - - bool retval = false; + bool retval = true; - string oct_file = oct_file_in_path (fcn_name); + if (! instance) + instance = new octave_dynamic_loader (); - if (! oct_file.empty ()) + if (! instance) { - builtin_fcn_installer f - = instance->resolve_reference (fcn_name, oct_file); + error ("unable to create dynamic loader object!"); - if (f) - retval = f (); + retval = false; } return retval; } -octave_dynamic_loader::builtin_fcn_installer -octave_dynamic_loader::resolve_reference (const string&, const string&) +static +void clear_function (const string& fcn_name) +{ + if (Vwarn_reload_forces_clear) + warning (" %s", fcn_name.c_str ()); + + curr_sym_tab->clear (fcn_name); + + if (curr_sym_tab != top_level_sym_tab) + top_level_sym_tab->clear (fcn_name); + + global_sym_tab->clear (fcn_name); +} + +bool +octave_dynamic_loader::do_load (const string& fcn_name) { - return 0; + bool retval = false; + + octave_shlib oct_file; + + unwind_protect::begin_frame ("octave_dynamic_loader::do_load"); + + unwind_protect_bool (octave_dynamic_loader::doing_load); + + doing_load = true; + + void *function + = octave_shlib_list::search (fcn_name, oct_file, mangle_name); + + if (! error_state) + { + if (function && oct_file.is_out_of_date ()) + { + int n = oct_file.number_of_functions_loaded (); + + if (n > 0 && Vwarn_reload_forces_clear) + warning ("reloading %s clears the following functions:", + oct_file.file_name().c_str ()); + + oct_file.close (clear_function); + + function = 0; + } + + if (! function) + { + string oct_file_name = oct_file_in_path (fcn_name); + + if (! oct_file_name.empty ()) + { + oct_file.open (oct_file_name, Vwarn_future_time_stamp); + + if (! error_state) + { + if (oct_file) + { + octave_shlib_list::append (oct_file); + + function = oct_file.search (fcn_name, mangle_name); + } + else + error ("%s is not a valid shared library", + oct_file_name.c_str ()); + } + } + } + } + + if (function) + { + octave_dld_fcn_installer f + = X_CAST (octave_dld_fcn_installer, function); + + retval = f (oct_file); + + if (! retval) + error ("failed to install dld function `%s'", fcn_name.c_str ()); + } + + unwind_protect::run_frame ("octave_dynamic_loader::do_load"); + + return retval; +} + +bool +octave_dynamic_loader::do_remove (const string& fcn_name, octave_shlib& shl) +{ + bool retval = false; + + // We don't need to do anything if this is called because we are in + // the process of reloading a .oct file that has changed. + + if (! doing_load) + { + retval = shl.remove (fcn_name); + + if (shl.number_of_functions_loaded () == 0) + octave_shlib_list::remove (shl); + } + + return retval; +} + +bool +octave_dynamic_loader::load (const string& fcn_name) +{ + return (instance_ok ()) ? instance->do_load (fcn_name) : false; +} + +bool +octave_dynamic_loader::remove (const string& fcn_name, octave_shlib& shl) +{ + return (instance_ok ()) ? instance->do_remove (fcn_name, shl) : false; } string @@ -288,10 +317,25 @@ string retval ("FS"); #endif retval.append (name); - retval.append ("__Fv"); + retval.append ("__FRC12octave_shlib"); return retval; } +static int +warn_reload_forces_clear (void) +{ + Vwarn_reload_forces_clear = check_preference ("warn_reload_forces_clear"); + + return 0; +} + +void +symbols_of_dynamic_ld (void) +{ + DEFVAR (warn_reload_forces_clear, 1.0, warn_reload_forces_clear, + "warn if reloading a .oct file forces other functions to be cleared"); +} + /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/dynamic-ld.h +++ b/src/dynamic-ld.h @@ -25,7 +25,7 @@ #include <string> -class octave_builtin; +#include "oct-shlib.h" class octave_dynamic_loader @@ -36,11 +36,11 @@ public: - typedef bool (*builtin_fcn_installer) (void); - virtual ~octave_dynamic_loader (void) { } - static bool load_fcn_from_dot_oct_file (const string& fcn_name); + static bool load (const string& fcn_name); + + static bool remove (const string& fcn_name, octave_shlib& shl); private: @@ -54,14 +54,15 @@ static bool instance_ok (void); - static void make_dynamic_loader (void); + bool do_load (const string& fcn_name); + + bool do_remove (const string& fcn_name, octave_shlib& shl); + + static bool doing_load; protected: - virtual builtin_fcn_installer - resolve_reference (const string& mangled_name, const string& oct_file); - - string mangle_name (const string& name); + static string mangle_name (const string& name); }; #endif
--- a/src/octave.cc +++ b/src/octave.cc @@ -52,7 +52,6 @@ #include <defaults.h> #include "defun.h" -#include "dynamic-ld.h" #include "error.h" #include "file-io.h" #include "input.h" @@ -319,6 +318,7 @@ initialize_error_handlers () { set_liboctave_error_handler (error); + set_liboctave_warning_handler (warning); } // What happens on --traditional.
--- a/src/ov-base.h +++ b/src/ov-base.h @@ -150,6 +150,10 @@ bool is_function (void) const { return false; } + bool is_builtin_function (void) const { return false; } + + bool is_dld_function (void) const { return false; } + int int_value (bool = false, bool = false) const; int nint_value (bool = false) const;
--- a/src/ov-builtin.cc +++ b/src/ov-builtin.cc @@ -46,7 +46,7 @@ for (int i = 0; i < nargin; i++) if (args(i).is_magic_colon ()) - return true; + return true; return false; }
--- a/src/ov-builtin.h +++ b/src/ov-builtin.h @@ -52,17 +52,21 @@ octave_function *function_value (bool) { return this; } + bool is_builtin_function (void) const { return true; } + octave_value_list do_index_op (int nargout, const octave_value_list& args); +protected: + + // A pointer to the actual function. + fcn f; + private: octave_builtin (void); octave_builtin (const octave_builtin& m); - // A pointer to the actual function. - fcn f; - DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA DECLARE_OCTAVE_ALLOCATOR
--- a/src/ov-fcn.h +++ b/src/ov-fcn.h @@ -30,6 +30,7 @@ #include <string> #include "oct-time.h" +#include "str-vec.h" #include "oct-alloc.h" #include "ov-base.h" @@ -57,6 +58,8 @@ bool is_function (void) const { return true; } + virtual bool is_dynamically_loaded_function (void) const { return false; } + virtual bool is_system_fcn_file (void) { return false; } virtual string fcn_file_name (void) const { return string (); } @@ -73,6 +76,8 @@ string doc_string (void) const { return doc; } + virtual void unload (void) { } + virtual void accept (tree_walker&) { } protected: @@ -80,16 +85,16 @@ octave_function (const string& nm, const string& ds) : my_name (nm), doc (ds) { } -private: - - octave_function (void); - // The name of this function. string my_name; // The help text for this function. string doc; +private: + + octave_function (void); + DECLARE_OCTAVE_ALLOCATOR };
--- a/src/ov-usr-fcn.h +++ b/src/ov-usr-fcn.h @@ -67,8 +67,7 @@ void stash_fcn_file_name (void); - void mark_fcn_file_up_to_date (const octave_time& t) - { t_checked = t; } + void mark_fcn_file_up_to_date (const octave_time& t) { t_checked = t; } void stash_fcn_file_time (const octave_time& t) {
--- a/src/ov.h +++ b/src/ov.h @@ -377,6 +377,12 @@ virtual bool is_function (void) const { return rep->is_function (); } + virtual bool is_builtin_function (void) const + { return rep->is_builtin_function (); } + + virtual bool is_dld_function (void) const + { return rep->is_dld_function (); } + // Values. octave_value eval (void) { return *this; }
--- a/src/parse.y +++ b/src/parse.y @@ -91,6 +91,10 @@ // should only produce output using explicit printing statements. static bool Vwarn_missing_semicolon; +// TRUE means we print a warning if reloading a .oct file forces other +// functions to be cleared. +static bool Vwarn_reload_forces_clear; + // Temporary symbol table pointer used to cope with bogus function syntax. symbol_table *tmp_local_sym_tab = 0; @@ -2996,7 +3000,7 @@ string nm = sym_rec->name (); - if (octave_dynamic_loader::load_fcn_from_dot_oct_file (nm)) + if (octave_dynamic_loader::load (nm)) { force_link_to_function (nm); } @@ -3293,6 +3297,14 @@ } static int +warn_reload_forces_clear (void) +{ + Vwarn_reload_forces_clear = check_preference ("warn_reload_forces_clear"); + + return 0; +} + +static int warn_variable_switch_label (void) { Vwarn_variable_switch_label @@ -3321,6 +3333,9 @@ "produce a warning if a statement in a function file is not\n\ terminated with a semicolon"); + DEFVAR (warn_reload_forces_clear, 1.0, warn_reload_forces_clear, + "warn if reloading a .oct file forces other functions to be cleared"); + DEFVAR (warn_variable_switch_label, 0.0, warn_variable_switch_label, "produce warning for variables used as switch labels"); }
--- a/src/symtab.cc +++ b/src/symtab.cc @@ -215,7 +215,7 @@ { symbol_def *hidden_def = definition->next_elem; - if (hidden_def && hidden_def->is_builtin_function ()) + if (hidden_def && hidden_def->is_user_function ()) retval = true; } @@ -231,7 +231,7 @@ { symbol_def *hidden_def = definition->next_elem; - if (hidden_def && hidden_def->is_user_function ()) + if (hidden_def && hidden_def->is_builtin_function ()) retval = true; } @@ -408,6 +408,9 @@ while (definition) remove_top_def (); + if (! sd) + sd = new symbol_def (); + push_def (sd); } @@ -488,7 +491,8 @@ while (ptr) { if (ptr->is_user_variable () - || (clear_user_functions && ptr->is_user_function ())) + || (clear_user_functions + && (ptr->is_user_function () || ptr->is_dld_function ()))) { ptr->clear (); } @@ -509,7 +513,8 @@ { if (ptr->name () == nm && (ptr->is_user_variable () - || (clear_user_functions && ptr->is_user_function ()))) + || (clear_user_functions + && (ptr->is_user_function () || ptr->is_dld_function ())))) { ptr->clear (); return true;
--- a/src/symtab.h +++ b/src/symtab.h @@ -53,18 +53,19 @@ public: // If you add or delete an entry here, you'll also need to change - // the with parameter in the declaration for symbol_type below... + // the width parameter in the declaration for symbol_type below... enum TYPE { UNKNOWN = 0, USER_FUNCTION = 1, USER_VARIABLE = 2, - BUILTIN_FUNCTION = 4, - TEXT_FUNCTION = 8, - MAPPER_FUNCTION = 16, - BUILTIN_VARIABLE = 32, - BUILTIN_CONSTANT = 64 + DLD_FUNCTION = 4, + BUILTIN_FUNCTION = 8, + TEXT_FUNCTION = 16, + MAPPER_FUNCTION = 32, + BUILTIN_VARIABLE = 64, + BUILTIN_CONSTANT = 128 }; private: @@ -94,6 +95,7 @@ bool is_function (void) const { return (symbol_type & symbol_record::USER_FUNCTION + || symbol_type & symbol_record::DLD_FUNCTION || symbol_type & symbol_record::BUILTIN_FUNCTION); } @@ -118,6 +120,9 @@ bool is_builtin_function (void) const { return (symbol_type & symbol_record::BUILTIN_FUNCTION); } + bool is_dld_function (void) const + { return (symbol_type & symbol_record::DLD_FUNCTION); } + // XXX FIXME XXX bool is_map_element (const string& /* elts */) const { return false; } @@ -165,7 +170,7 @@ static octave_allocator allocator; // The type of this symbol (see the enum above). - unsigned int symbol_type : 7; + unsigned int symbol_type : 8; // Nonzero means this variable cannot be cleared. unsigned int eternal : 1; @@ -235,6 +240,9 @@ bool is_builtin_function (void) const { return definition->is_builtin_function (); } + bool is_dld_function (void) const + { return definition->is_dld_function (); } + bool is_constant (void) const { return definition->is_constant (); } @@ -357,6 +365,7 @@ #define SYMTAB_ALL_TYPES (symbol_record::USER_FUNCTION \ | symbol_record::USER_VARIABLE \ + | symbol_record::DLD_FUNCTION \ | symbol_record::BUILTIN_FUNCTION \ | symbol_record::TEXT_FUNCTION \ | symbol_record::MAPPER_FUNCTION \
--- a/src/toplev.cc +++ b/src/toplev.cc @@ -52,7 +52,6 @@ #include <defaults.h> #include "defun.h" -#include "dynamic-ld.h" #include "error.h" #include "file-io.h" #include "input.h"
--- a/src/variables.cc +++ b/src/variables.cc @@ -520,7 +520,12 @@ { time_t tp = tmp->time_parsed (); - string fname = fcn_file_in_path (ff); + string fname; + + if (tmp->is_dld_function ()) + fname = ff; + else + fname = fcn_file_in_path (ff); tmp->mark_fcn_file_up_to_date (octave_time ()); @@ -1082,17 +1087,16 @@ { string_vector tmp; - lvars = curr_sym_tab->name_list (lcount, tmp, false, - SYMTAB_VARIABLES, - SYMTAB_LOCAL_SCOPE); + lvars = curr_sym_tab->name_list + (lcount, tmp, false, SYMTAB_VARIABLES, SYMTAB_LOCAL_SCOPE); - gvars = curr_sym_tab->name_list (gcount, tmp, false, - SYMTAB_VARIABLES, - SYMTAB_GLOBAL_SCOPE); + gvars = curr_sym_tab->name_list + (gcount, tmp, false, SYMTAB_VARIABLES, SYMTAB_GLOBAL_SCOPE); - fcns = global_sym_tab->name_list (fcount, tmp, false, - symbol_record::USER_FUNCTION, - SYMTAB_ALL_SCOPES); + fcns = global_sym_tab->name_list + (fcount, tmp, false, + symbol_record::USER_FUNCTION|symbol_record::DLD_FUNCTION, + SYMTAB_ALL_SCOPES); } // XXX FIXME XXX -- this needs to be optimized to avoid the
--- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,7 @@ +1999-10-29 John W. Eaton <jwe@bevo.che.wisc.edu> + + * octave.test/system/mktime-1.m (t): Compare whole seconds only. + Fri Dec 4 20:55:47 1998 John W. Eaton <jwe@bevo.che.wisc.edu> * octave.test/system/clock-1.m: Use standard format specifiers %d