changeset 13983:7dd7cccf0757

clean up memory allocated for singletons before exit * singleton-cleanup.h, singleton-cleanup.cc: New files. * liboctave/Makefile.am (INCS, LIBOCTAVE_CXX_SOURCES): Add them to the lists. * toplev.cc (clean_up_and_exit): Call singleton_cleanup_list::cleanup. * debug.h, debug.cc (bp_table::instance_ok): Move definition to debug.cc. * coment-list.h (octave_comment_buffer::~octave_comment_buffer): Define destructor for class. * ov-typeinfo.h (octave_value_typeinfo::~octave_value_typeinfo): Likewise. * cmd-edit.h (command_editor::cleanup_instance): New function. * cmd-hist.h (command_history::cleanup_instance): New function. * file-ops.h (file_ops::cleanup_instance): New function. * mach-info.h (oct_mach_info::cleanup_instance): New function. * oct-env.h (octave_env::cleanup_instance): New function. * oct-fftw.h (octave_fftw_planner::cleanup_instance): New function. * oct-rand.h (octave_rand::cleanup_instance): New function. * oct-spparms.h (octave_sparse_params::cleanup_instance): New function. * pathsearch.h (static_members::cleanup_instance): New function. * comment-list.h (octave_comment_buffer::cleanup_instance): New function. * debug.h (bp_table::cleanup_instance): New function. * display.h (display_info::cleanup_instance): New function. * dynamic-ld.cc (octave_shlib_list::cleanup_instance, octave_mex_file_list::cleanup_instance): New functions. * dynamic-ld.h (octave_dynamic_loader::cleanup_instance): New function. * load-path.h (load_path::cleanup_instance): New function. * oct-stream.h (octave_stream_list::cleanup_instance): New function. * ov-typeinfo.h (octave_value_typeinfo::cleanup_instance): New function. * pager.h, pager.cc (octave_pager_stream::instance_ok, octave_pager_stream::cleanup_instance): New functions. (octave_diary_stream::instance_ok, octave_diary_stream::cleanup_instance): New functions. * sighandlers.h (octave_child_list::cleanup_instance): New function. * toplev.h (octave_call_stack * pager.cc (octave_pager_stream::stream, octave_diary_stream::stream): Use instance_ok to create instance. * toplev.h (octave_call_stack::cleanup_instance): New function. * cmd-edit.cc (command_editor::instance_ok): Register cleanup function. * cmd-hist.cc (command_history::instance_ok): Likewise. * file-ops.cc (file_ops::instance_ok): Likewise. * mach-info.cc (oct_mach_info::instance_ok): Likewise. * oct-env.cc (octave_env::instance_ok): Likewise. * oct-fftw.cc (octave_fftw_planner::instance_ok): Likewise. * oct-rand.cc (octave_rand::instance_ok): Likewise. * oct-spparms.cc (octave_sparse_params::instance_ok): Likewise. * pathsearch.cc (dir_path::static_members::instance_ok): Likewise. * comment-list.cc (comment_list::instance_ok): Likewise. * debug.cc (bp_table::instance_ok): Likewise. * display.cc (display_info::instance_ok): Likewise. * dynamic-ld.cc (octave_shlib_list::instance_ok, octave_mex_file_list::instance_ok, octave_dynamic_loader): Likewise. * load-path.cc (load_path::instance_ok): Likewise. * oct-stream.cc (octave_stream_list::instance_ok): Likewise. * ov-typeinfo.cc (octave_value_typeinfo::instance_ok): Likewise. * sighandlers.cc (octave_child_list::instance_ok): Likewise. * symtab.h, symtab.cc (symbol_table::scope_id::create_instance): New function. * symtab.h (symbol_table::scope_id::instance_ok): Call create_instance. * toplev.h, toplev.cc (octave_call_stack::create_instance): New function. * toplev.cc (octave_call_stack::instance_ok): Call create_instance. * pager.h, pager.cc (octave_pager_stream::set_diary_skip, octave_pager_stream::flush_current_contents_to_diary): Now static. octave_pager_stream::do_set_diary_skip, octave_pager_stream::do_flush_current_contents_to_diary): New functions. (octave_pager_stream::stream): Return std::ostream&, not octave_pager_stream&. If instance creation fails, return std::cout. (octave_diary_stream::stream): Return std::ostream&, not octave_diary_stream&. If instance creation fails, return std::cout. (octave_pager_stream::do_reset, octave_diary_stream::do_reset): Use instance_ok to create instance.
author John W. Eaton <jwe@octave.org>
date Sat, 03 Dec 2011 04:34:17 -0500
parents 6cdfbe90e2ab
children 1126c2907878
files liboctave/Makefile.am liboctave/cmd-edit.cc liboctave/cmd-edit.h liboctave/cmd-hist.cc liboctave/cmd-hist.h liboctave/file-ops.cc liboctave/file-ops.h liboctave/mach-info.cc liboctave/mach-info.h liboctave/oct-env.cc liboctave/oct-env.h liboctave/oct-fftw.cc liboctave/oct-fftw.h liboctave/oct-rand.cc liboctave/oct-rand.h liboctave/oct-spparms.cc liboctave/oct-spparms.h liboctave/pathsearch.cc liboctave/pathsearch.h liboctave/singleton-cleanup.cc liboctave/singleton-cleanup.h src/comment-list.cc src/comment-list.h src/debug.cc src/debug.h src/display.cc src/display.h src/dynamic-ld.cc src/dynamic-ld.h src/load-path.cc src/load-path.h src/oct-stream.cc src/oct-stream.h src/ov-typeinfo.cc src/ov-typeinfo.h src/pager.cc src/pager.h src/sighandlers.cc src/sighandlers.h src/symtab.cc src/symtab.h src/toplev.cc src/toplev.h
diffstat 43 files changed, 459 insertions(+), 101 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Makefile.am	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/Makefile.am	Sat Dec 03 04:34:17 2011 -0500
@@ -244,6 +244,7 @@
   randmtzig.h \
   randpoisson.h \
   regex-match.h \
+  singleton-cleanup.h \
   sparse-sort.h \
   sparse-util.h \
   statdefs.h \
@@ -452,6 +453,7 @@
   oct-uname.cc \
   pathsearch.cc \
   regex-match.cc \
+  singleton-cleanup.cc \
   sparse-sort.cc \
   sparse-util.cc \
   str-vec.cc \
--- a/liboctave/cmd-edit.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/cmd-edit.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -42,6 +42,7 @@
 #include "oct-env.h"
 #include "oct-mutex.h"
 #include "oct-time.h"
+#include "singleton-cleanup.h"
 
 command_editor *command_editor::instance = 0;
 
@@ -831,7 +832,12 @@
   bool retval = true;
 
   if (! instance)
-    make_command_editor ();
+    {
+      make_command_editor ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
   if (! instance)
     {
--- a/liboctave/cmd-edit.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/cmd-edit.h	Sat Dec 03 04:34:17 2011 -0500
@@ -184,6 +184,8 @@
   // The real thing.
   static command_editor *instance;
 
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
 protected:
 
   // To use something other than the GNU readline library, derive a new
--- a/liboctave/cmd-hist.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/cmd-hist.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -49,6 +49,7 @@
 #include "oct-rl-hist.h"
 
 #include "file-stat.h"
+#include "singleton-cleanup.h"
 
 class
 gnu_history : public command_history
@@ -467,7 +468,12 @@
   bool retval = true;
 
   if (! instance)
-    make_command_history ();
+    {
+      make_command_history ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
   if (! instance)
     {
--- a/liboctave/cmd-hist.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/cmd-hist.h	Sat Dec 03 04:34:17 2011 -0500
@@ -126,6 +126,8 @@
   // The real thing.
   static command_history *instance;
 
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
 protected:
 
   // To use something other than the GNU history library, derive a new
--- a/liboctave/file-ops.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/file-ops.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -42,11 +42,12 @@
 #include "file-ops.h"
 #include "file-stat.h"
 #include "oct-env.h"
+#include "oct-locbuf.h"
 #include "oct-passwd.h"
 #include "pathlen.h"
 #include "quit.h"
+#include "singleton-cleanup.h"
 #include "str-vec.h"
-#include "oct-locbuf.h"
 
 file_ops *file_ops::instance = 0;
 
@@ -73,13 +74,16 @@
       instance = new file_ops (system_dir_sep_char, system_dir_sep_str,
                                system_dir_sep_chars);
 
-      if (! instance)
-        {
-          (*current_liboctave_error_handler)
-            ("unable to create file_ops object!");
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
-          retval = false;
-        }
+  if (! instance)
+    {
+      (*current_liboctave_error_handler)
+        ("unable to create file_ops object!");
+
+      retval = false;
     }
 
   return retval;
--- a/liboctave/file-ops.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/file-ops.h	Sat Dec 03 04:34:17 2011 -0500
@@ -99,6 +99,8 @@
 
   static file_ops *instance;
 
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
   // No copying!
 
   file_ops (const file_ops&);
--- a/liboctave/mach-info.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/mach-info.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -27,6 +27,7 @@
 #include "f77-fcn.h"
 #include "lo-error.h"
 #include "mach-info.h"
+#include "singleton-cleanup.h"
 
 extern "C"
 {
@@ -163,7 +164,12 @@
   bool retval = true;
 
   if (! instance)
-    instance = new oct_mach_info ();
+    {
+      instance = new oct_mach_info ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
   if (! instance)
     {
--- a/liboctave/mach-info.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/mach-info.h	Sat Dec 03 04:34:17 2011 -0500
@@ -61,6 +61,8 @@
 
   static oct_mach_info *instance;
 
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
   // The floating point format for the current machine.
   mutable float_format native_float_fmt;
 
--- a/liboctave/oct-env.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/oct-env.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -58,6 +58,7 @@
 #include "oct-env.h"
 #include "oct-passwd.h"
 #include "oct-syscalls.h"
+#include "singleton-cleanup.h"
 
 octave_env::octave_env (void)
   : follow_symbolic_links (true), verbatim_pwd (true),
@@ -81,7 +82,12 @@
   bool retval = true;
 
   if (! instance)
-    instance = new octave_env ();
+    {
+      instance = new octave_env ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
   if (! instance)
     {
--- a/liboctave/oct-env.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/oct-env.h	Sat Dec 03 04:34:17 2011 -0500
@@ -115,6 +115,9 @@
   // The real thing.
   static octave_env *instance;
 
+
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
   // TRUE means follow symbolic links that point to directories just
   // as if they are real directories.
   bool follow_symbolic_links;
--- a/liboctave/oct-fftw.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/oct-fftw.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -33,6 +33,7 @@
 #include "oct-fftw.h"
 #include "quit.h"
 #include "oct-locbuf.h"
+#include "singleton-cleanup.h"
 
 octave_fftw_planner *octave_fftw_planner::instance = 0;
 
@@ -75,7 +76,12 @@
   bool retval = true;
 
   if (! instance)
-    instance = new octave_fftw_planner ();
+    {
+      instance = new octave_fftw_planner ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
   if (! instance)
     {
--- a/liboctave/oct-fftw.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/oct-fftw.h	Sat Dec 03 04:34:17 2011 -0500
@@ -108,6 +108,8 @@
 
   static octave_fftw_planner *instance;
 
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
   fftw_plan
   do_create_plan (int dir, const int rank, const dim_vector dims,
                   octave_idx_type howmany, octave_idx_type stride,
--- a/liboctave/oct-rand.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/oct-rand.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -29,18 +29,19 @@
 
 #include <stdint.h>
 
+#include "data-conv.h"
 #include "f77-fcn.h"
+#include "lo-error.h"
 #include "lo-ieee.h"
-#include "lo-error.h"
 #include "lo-mappers.h"
+#include "mach-info.h"
+#include "oct-locbuf.h"
 #include "oct-rand.h"
 #include "oct-time.h"
-#include "data-conv.h"
+#include "randgamma.h"
 #include "randmtzig.h"
 #include "randpoisson.h"
-#include "randgamma.h"
-#include "mach-info.h"
-#include "oct-locbuf.h"
+#include "singleton-cleanup.h"
 
 extern "C"
 {
@@ -89,7 +90,12 @@
   bool retval = true;
 
   if (! instance)
-    instance = new octave_rand ();
+    {
+      instance = new octave_rand ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
   if (! instance)
     {
--- a/liboctave/oct-rand.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/oct-rand.h	Sat Dec 03 04:34:17 2011 -0500
@@ -160,6 +160,8 @@
 
   static octave_rand *instance;
 
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
   enum
   {
     unknown_dist,
--- a/liboctave/oct-spparms.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/oct-spparms.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -29,6 +29,7 @@
 #include "lo-ieee.h"
 
 #include "oct-spparms.h"
+#include "singleton-cleanup.h"
 
 octave_sparse_params *octave_sparse_params::instance = 0;
 
@@ -38,7 +39,12 @@
   bool retval = true;
 
   if (! instance)
-    instance = new octave_sparse_params ();
+    {
+      instance = new octave_sparse_params ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
   if (! instance)
     {
--- a/liboctave/oct-spparms.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/oct-spparms.h	Sat Dec 03 04:34:17 2011 -0500
@@ -95,6 +95,8 @@
 
   static octave_sparse_params *instance;
 
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
   void do_defaults (void);
 
   void do_tight (void);
--- a/liboctave/pathsearch.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/pathsearch.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -31,7 +31,7 @@
 #include "lo-utils.h"
 #include "oct-env.h"
 #include "pathsearch.h"
-#include "str-vec.h"
+#include "singleton-cleanup.h"
 #include "str-vec.h"
 
 #include "kpse.cc"
@@ -47,7 +47,12 @@
   bool retval = true;
 
   if (! instance)
-    instance = new static_members ();
+    {
+      instance = new static_members ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
   if (! instance)
     {
--- a/liboctave/pathsearch.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/liboctave/pathsearch.h	Sat Dec 03 04:34:17 2011 -0500
@@ -153,6 +153,8 @@
 
     static static_members *instance;
 
+    static void cleanup_instance (void) { delete instance; instance = 0; }
+
     static bool instance_ok (void);
 
     // No copying!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/singleton-cleanup.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -0,0 +1,60 @@
+/*
+
+Copyright (C) 2011 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 3 of the License, 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, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <lo-error.h>
+#include <singleton-cleanup.h>
+
+singleton_cleanup_list *singleton_cleanup_list::instance = 0;
+
+singleton_cleanup_list::~singleton_cleanup_list (void)
+{
+  for (std::set<fptr>::iterator p = fcn_list.begin ();
+       p != fcn_list.end (); p++)
+    {
+      fptr fcn = *p;
+
+      fcn ();
+    }
+}
+
+bool
+singleton_cleanup_list::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    instance = new singleton_cleanup_list ();
+
+  if (! instance)
+    {
+      current_liboctave_error_handler
+        ("unable to create singleton_cleanup_list object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/singleton-cleanup.h	Sat Dec 03 04:34:17 2011 -0500
@@ -0,0 +1,49 @@
+#if !defined (octave_singleton_cleanup_h)
+#define octave_singleton_cleanup_h 1
+
+#include <set>
+
+class
+singleton_cleanup_list
+{
+protected:
+
+  singleton_cleanup_list (void) : fcn_list () { }
+
+public:
+
+  typedef void (*fptr) (void);
+
+  ~singleton_cleanup_list (void);
+
+  static void add (fptr f)
+  {
+    if (instance_ok ())
+      instance->do_add (f);
+  }
+
+  static void cleanup (void) { delete instance; instance = 0; }
+
+private:
+
+  static singleton_cleanup_list *instance;
+
+  static bool instance_ok (void);
+
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
+  std::set<fptr> fcn_list;
+
+  void do_add (fptr f)
+  {
+    fcn_list.insert (f);
+  }
+
+  // No copying!
+
+  singleton_cleanup_list (const singleton_cleanup_list&);
+
+  singleton_cleanup_list& operator = (const singleton_cleanup_list&);
+};
+
+#endif
--- a/src/comment-list.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/comment-list.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -25,6 +25,7 @@
 #endif
 
 #include "lo-utils.h"
+#include "singleton-cleanup.h"
 
 #include "comment-list.h"
 #include "error.h"
@@ -52,7 +53,12 @@
   bool retval = true;
 
   if (! instance)
-    instance = new octave_comment_buffer ();
+    {
+      instance = new octave_comment_buffer ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
   if (! instance)
     {
--- a/src/comment-list.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/comment-list.h	Sat Dec 03 04:34:17 2011 -0500
@@ -105,6 +105,8 @@
   octave_comment_buffer (void)
     : comment_list (new octave_comment_list ()) { }
 
+  ~octave_comment_buffer (void) { delete comment_list; }
+
   static bool instance_ok (void);
 
   static void append
@@ -122,6 +124,8 @@
   octave_comment_list *comment_list;
 
   static octave_comment_buffer *instance;
+
+  static void cleanup_instance (void) { delete instance; instance = 0; }
 };
 
 #endif
--- a/src/debug.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/debug.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -32,6 +32,7 @@
 #include <string>
 
 #include "file-stat.h"
+#include "singleton-cleanup.h"
 
 #include "defun.h"
 #include "error.h"
@@ -250,6 +251,28 @@
     }
 }
 
+bool
+bp_table::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    {
+      instance = new bp_table ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
+
+  if (! instance)
+    {
+      ::error ("unable to create breakpoint table!");
+      retval = false;
+    }
+
+  return retval;
+}
+
 bp_table::intmap
 bp_table::do_add_breakpoint (const std::string& fname,
                              const bp_table::intmap& line)
--- a/src/debug.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/debug.h	Sat Dec 03 04:34:17 2011 -0500
@@ -55,21 +55,7 @@
   typedef fname_line_map::const_iterator const_fname_line_map_iterator;
   typedef fname_line_map::iterator fname_line_map_iterator;
 
-  static bool instance_ok (void)
-  {
-    bool retval = true;
-
-    if (! instance)
-      instance = new bp_table ();
-
-    if (! instance)
-      {
-        ::error ("unable to create breakpoint table!");
-        retval = false;
-      }
-
-    return retval;
-  }
+  static bool instance_ok (void);
 
   // Add a breakpoint at the nearest executable line.
   static intmap add_breakpoint (const std::string& fname = "",
@@ -127,6 +113,8 @@
 
   static bp_table *instance;
 
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
   intmap do_add_breakpoint (const std::string& fname, const intmap& lines);
 
   int do_remove_breakpoint (const std::string&, const intmap& lines);
--- a/src/display.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/display.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -34,6 +34,8 @@
 #include <X11/Xlib.h>
 #endif
 
+#include "singleton-cleanup.h"
+
 #include "display.h"
 #include "error.h"
 
@@ -138,7 +140,12 @@
   bool retval = true;
 
   if (! instance)
-    instance = new display_info (query);
+    {
+      instance = new display_info (query);
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
   if (! instance)
     {
--- a/src/display.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/display.h	Sat Dec 03 04:34:17 2011 -0500
@@ -73,6 +73,8 @@
 
   static display_info *instance;
 
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
   // Height, width, and depth of the display.
   int ht;
   int wd;
--- a/src/dynamic-ld.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/dynamic-ld.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -27,9 +27,10 @@
 #include <iostream>
 #include <list>
 
+#include "file-stat.h"
 #include "oct-env.h"
 #include "oct-time.h"
-#include "file-stat.h"
+#include "singleton-cleanup.h"
 
 #include <defaults.h>
 
@@ -78,6 +79,8 @@
 
   static octave_shlib_list *instance;
 
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
   static bool instance_ok (void);
 
   // List of libraries we have loaded.
@@ -148,7 +151,12 @@
   bool retval = true;
 
   if (! instance)
-    instance = new octave_shlib_list ();
+    {
+      instance = new octave_shlib_list ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
   if (! instance)
     {
@@ -213,6 +221,8 @@
 
   static octave_mex_file_list *instance;
 
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
   static bool instance_ok (void);
 
   // List of libraries we have loaded.
@@ -258,7 +268,12 @@
   bool retval = true;
 
   if (! instance)
-    instance = new octave_mex_file_list ();
+    {
+      instance = new octave_mex_file_list ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
   if (! instance)
     {
@@ -295,7 +310,12 @@
   bool retval = true;
 
   if (! instance)
-    instance = new octave_dynamic_loader ();
+    {
+      instance = new octave_dynamic_loader ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
   if (! instance)
     {
--- a/src/dynamic-ld.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/dynamic-ld.h	Sat Dec 03 04:34:17 2011 -0500
@@ -64,6 +64,8 @@
 
   static octave_dynamic_loader *instance;
 
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
   static bool instance_ok (void);
 
   octave_function *
--- a/src/load-path.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/load-path.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -32,6 +32,7 @@
 #include "file-stat.h"
 #include "oct-env.h"
 #include "pathsearch.h"
+#include "singleton-cleanup.h"
 
 #include "defaults.h"
 #include "defun.h"
@@ -290,7 +291,12 @@
   bool retval = true;
 
   if (! instance)
-    instance = new load_path ();
+    {
+      instance = new load_path ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
   if (! instance)
     {
--- a/src/load-path.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/load-path.h	Sat Dec 03 04:34:17 2011 -0500
@@ -443,6 +443,8 @@
 
   static load_path *instance;
 
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
   static hook_fcn_ptr add_hook;
 
   static hook_fcn_ptr remove_hook;
--- a/src/oct-stream.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/oct-stream.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -40,8 +40,9 @@
 #include "lo-ieee.h"
 #include "lo-mappers.h"
 #include "lo-utils.h"
+#include "quit.h"
+#include "singleton-cleanup.h"
 #include "str-vec.h"
-#include "quit.h"
 
 #include "error.h"
 #include "gripes.h"
@@ -3916,7 +3917,12 @@
   bool retval = true;
 
   if (! instance)
-    instance = new octave_stream_list ();
+    {
+      instance = new octave_stream_list ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
   if (! instance)
     {
--- a/src/oct-stream.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/oct-stream.h	Sat Dec 03 04:34:17 2011 -0500
@@ -689,6 +689,8 @@
 
   static octave_stream_list *instance;
 
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
   int do_insert (octave_stream& os);
 
   octave_stream do_lookup (int fid, const std::string& who = std::string ()) const;
--- a/src/ov-typeinfo.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/ov-typeinfo.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -24,10 +24,12 @@
 #include <config.h>
 #endif
 
-#include "ov-typeinfo.h"
+#include "Array.h"
+#include "singleton-cleanup.h"
 
 #include "defun.h"
 #include "error.h"
+#include "ov-typeinfo.h"
 
 const int
 octave_value_typeinfo::init_tab_sz (16);
@@ -35,14 +37,18 @@
 octave_value_typeinfo *
 octave_value_typeinfo::instance (0);
 
-#include <Array.h>
-
 bool
 octave_value_typeinfo::instance_ok (void)
 {
   bool retval = true;
+
   if (! instance)
-    instance = new octave_value_typeinfo ();
+    {
+      instance = new octave_value_typeinfo ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
   if (! instance)
     {
--- a/src/ov-typeinfo.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/ov-typeinfo.h	Sat Dec 03 04:34:17 2011 -0500
@@ -208,12 +208,16 @@
       type_conv_ops (dim_vector (init_tab_sz, init_tab_sz), 0),
       widening_ops (dim_vector (init_tab_sz, init_tab_sz), 0)  { }
 
+  ~octave_value_typeinfo (void) { }
+
 private:
 
   static const int init_tab_sz;
 
   static octave_value_typeinfo *instance;
 
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
   int num_types;
 
   Array<std::string> types;
--- a/src/pager.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/pager.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -30,16 +30,16 @@
 
 #include "cmd-edit.h"
 #include "oct-env.h"
+#include "singleton-cleanup.h"
 
-#include "procstream.h"
-
-#include <defaults.h>
+#include "defaults.h"
 #include "defun.h"
 #include "error.h"
 #include "gripes.h"
 #include "input.h"
 #include "oct-obj.h"
 #include "pager.h"
+#include "procstream.h"
 #include "sighandlers.h"
 #include "unwind-prot.h"
 #include "utils.h"
@@ -311,27 +311,24 @@
   delete pb;
 }
 
-octave_pager_stream&
+std::ostream&
 octave_pager_stream::stream (void)
 {
-  if (! instance)
-    instance = new octave_pager_stream ();
-
-  return *instance;
+  return instance_ok () ? *instance : std::cout;
 }
 
 void
 octave_pager_stream::flush_current_contents_to_diary (void)
 {
-  if (pb)
-    pb->flush_current_contents_to_diary ();
+  if (instance_ok ())
+    instance->flush_current_contents_to_diary ();
 }
 
 void
 octave_pager_stream::set_diary_skip (void)
 {
-  if (pb)
-    pb->set_diary_skip ();
+  if (instance_ok ())
+    instance->do_set_diary_skip ();
 }
 
 // Reinitialize the pager buffer to avoid hanging on to large internal
@@ -342,10 +339,22 @@
 void
 octave_pager_stream::reset (void)
 {
-  if (! instance)
-    instance = new octave_pager_stream ();
+  if (instance_ok ())
+    instance->do_reset ();
+}
 
-  instance->do_reset ();
+void
+octave_pager_stream::do_flush_current_contents_to_diary (void)
+{
+  if (pb)
+    pb->flush_current_contents_to_diary ();
+}
+
+void
+octave_pager_stream::do_set_diary_skip (void)
+{
+  if (pb)
+    pb->set_diary_skip ();
 }
 
 void
@@ -357,6 +366,29 @@
   setf (unitbuf);
 }
 
+bool
+octave_pager_stream::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    {
+      instance = new octave_pager_stream ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
+
+  if (! instance)
+    {
+      ::error ("unable to create pager_stream object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
 octave_diary_stream *octave_diary_stream::instance = 0;
 
 octave_diary_stream::octave_diary_stream (void) : std::ostream (0), db (0)
@@ -372,13 +404,10 @@
   delete db;
 }
 
-octave_diary_stream&
+std::ostream&
 octave_diary_stream::stream (void)
 {
-  if (! instance)
-    instance = new octave_diary_stream ();
-
-  return *instance;
+  return instance_ok () ? *instance : std::cout;
 }
 
 // Reinitialize the diary buffer to avoid hanging on to large internal
@@ -389,10 +418,8 @@
 void
 octave_diary_stream::reset (void)
 {
-  if (! instance)
-    instance = new octave_diary_stream ();
-
-  instance->do_reset ();
+  if (instance_ok ())
+    instance->do_reset ();
 }
 
 void
@@ -404,6 +431,29 @@
   setf (unitbuf);
 }
 
+bool
+octave_diary_stream::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    {
+      instance = new octave_diary_stream ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
+
+  if (! instance)
+    {
+      ::error ("unable to create diary_stream object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
 void
 flush_octave_stdout (void)
 {
@@ -437,7 +487,7 @@
   //
   // will do the right thing.
 
-  octave_stdout.flush_current_contents_to_diary ();
+  octave_pager_stream::flush_current_contents_to_diary ();
 
   if (external_diary_file.is_open ())
     {
@@ -454,7 +504,7 @@
   // If there is pending output in the pager buf, it should not go
   // into the diary file.
 
-  octave_stdout.set_diary_skip ();
+  octave_pager_stream::set_diary_skip ();
 
   external_diary_file.open (diary_file.c_str (), std::ios::app);
 
--- a/src/pager.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/pager.h	Sat Dec 03 04:34:17 2011 -0500
@@ -62,20 +62,28 @@
 
   ~octave_pager_stream (void);
 
-  void flush_current_contents_to_diary (void);
+  static void flush_current_contents_to_diary (void);
 
-  void set_diary_skip (void);
+  static void set_diary_skip (void);
 
-  static octave_pager_stream& stream (void);
+  static std::ostream& stream (void);
 
   static void reset (void);
 
 private:
 
+  void do_flush_current_contents_to_diary (void);
+
+  void do_set_diary_skip (void);
+
   void do_reset (void);
 
   static octave_pager_stream *instance;
 
+  static bool instance_ok (void);
+
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
   octave_pager_buf *pb;
 
   // No copying!
@@ -110,7 +118,7 @@
 
   ~octave_diary_stream (void);
 
-  static octave_diary_stream& stream (void);
+  static std::ostream& stream (void);
 
   static void reset (void);
 
@@ -120,6 +128,10 @@
 
   static octave_diary_stream *instance;
 
+  static bool instance_ok (void);
+
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
   octave_diary_buf *db;
 
   // No copying!
--- a/src/sighandlers.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/sighandlers.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -35,6 +35,7 @@
 #include "cmd-edit.h"
 #include "oct-syscalls.h"
 #include "quit.h"
+#include "singleton-cleanup.h"
 
 #include "debug.h"
 #include "defun.h"
@@ -804,7 +805,12 @@
   bool retval = true;
 
   if (! instance)
-    instance = new octave_child_list_rep ();
+    {
+      instance = new octave_child_list_rep ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
 
   if (! instance)
     {
--- a/src/sighandlers.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/sighandlers.h	Sat Dec 03 04:34:17 2011 -0500
@@ -170,6 +170,8 @@
   static bool instance_ok (void);
 
   static octave_child_list_rep *instance;
+
+  static void cleanup_instance (void) { delete instance; instance = 0; }
 };
 
 #endif
--- a/src/symtab.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/symtab.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -25,24 +25,25 @@
 #include <config.h>
 #endif
 
+#include "file-ops.h"
+#include "file-stat.h"
 #include "oct-env.h"
 #include "oct-time.h"
-#include "file-ops.h"
-#include "file-stat.h"
+#include "singleton-cleanup.h"
 
+#include "debug.h"
 #include "defun.h"
 #include "dirfns.h"
 #include "input.h"
 #include "load-path.h"
-#include "symtab.h"
 #include "ov-fcn.h"
 #include "ov-usr-fcn.h"
 #include "pager.h"
 #include "parse.h"
 #include "pt-arg-list.h"
+#include "symtab.h"
 #include "unwind-prot.h"
 #include "utils.h"
-#include "debug.h"
 
 symbol_table *symbol_table::instance = 0;
 
@@ -70,6 +71,14 @@
 static int Vignore_function_time_stamp = 1;
 
 void
+symbol_table::scope_id_cache::create_instance (void)
+{
+  instance = new scope_id_cache ();
+
+  singleton_cleanup_list::add (cleanup_instance);
+}
+
+void
 symbol_table::symbol_record::symbol_record_rep::dump
   (std::ostream& os, const std::string& prefix) const
 {
--- a/src/symtab.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/symtab.h	Sat Dec 03 04:34:17 2011 -0500
@@ -81,12 +81,14 @@
       return instance_ok () ? instance->do_scopes () : std::list<scope_id> ();
     }
 
+    static void create_instance (void);
+
     static bool instance_ok (void)
     {
       bool retval = true;
 
       if (! instance)
-        instance = new scope_id_cache ();
+        create_instance ();
 
       if (! instance)
         {
@@ -108,6 +110,8 @@
 
     static scope_id_cache *instance;
 
+    static void cleanup_instance (void) { delete instance; instance = 0; }
+
     // The next available scope not in the free list.
     scope_id next_available;
 
--- a/src/toplev.cc	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/toplev.cc	Sat Dec 03 04:34:17 2011 -0500
@@ -44,25 +44,26 @@
 #include "lo-error.h"
 #include "lo-mappers.h"
 #include "oct-env.h"
+#include "oct-locbuf.h"
 #include "quit.h"
+#include "singleton-cleanup.h"
 #include "str-vec.h"
-#include "oct-locbuf.h"
 
-#include <defaults.h>
+#include "defaults.h"
 #include "defun.h"
 #include "error.h"
 #include "file-io.h"
 #include "input.h"
 #include "lex.h"
-#include <oct-conf.h>
+#include "oct-conf.h"
 #include "oct-hist.h"
 #include "oct-map.h"
 #include "oct-obj.h"
+#include "ov.h"
 #include "pager.h"
 #include "parse.h"
 #include "pathsearch.h"
 #include "procstream.h"
-#include "ov.h"
 #include "pt-eval.h"
 #include "pt-jump.h"
 #include "pt-stmt.h"
@@ -73,7 +74,7 @@
 #include "unwind-prot.h"
 #include "utils.h"
 #include "variables.h"
-#include <version.h>
+#include "version.h"
 
 void (*octave_exit) (int) = ::exit;
 
@@ -97,6 +98,19 @@
 
 octave_call_stack *octave_call_stack::instance = 0;
 
+void
+octave_call_stack::create_instance (void)
+{
+  instance = new octave_call_stack ();
+
+  if (instance)
+    {
+      instance->do_push (0, symbol_table::top_scope (), 0);
+
+      singleton_cleanup_list::add (cleanup_instance);
+    }
+}
+
 int
 octave_call_stack::do_current_line (void) const
 {
@@ -674,12 +688,14 @@
   do_octave_atexit ();
 
   // Clean up symbol table.
-  SAFE_CALL (symbol_table::cleanup, ());
+  SAFE_CALL (symbol_table::cleanup, ())
 
-  SAFE_CALL (cleanup_parser, ());
+  SAFE_CALL (cleanup_parser, ())
 
   SAFE_CALL (sysdep_cleanup, ())
 
+  SAFE_CALL (singleton_cleanup_list::cleanup, ())
+
   SAFE_CALL (octave_chunk_buffer::clear, ())
 
   if (octave_exit)
--- a/src/toplev.h	Sat Dec 03 03:30:37 2011 -0500
+++ b/src/toplev.h	Sat Dec 03 04:34:17 2011 -0500
@@ -112,22 +112,20 @@
   typedef std::deque<call_stack_elt>::reverse_iterator reverse_iterator;
   typedef std::deque<call_stack_elt>::const_reverse_iterator const_reverse_iterator;
 
+  static void create_instance (void);
+  
   static bool instance_ok (void)
   {
     bool retval = true;
 
     if (! instance)
-      {
-        instance = new octave_call_stack ();
+      create_instance ();
 
-        if (instance)
-          instance->do_push (0, symbol_table::top_scope (), 0);
-        else
-          {
-            ::error ("unable to create call stack object!");
+    if (! instance)
+      {
+        ::error ("unable to create call stack object!");
 
-            retval = false;
-          }
+        retval = false;
       }
 
     return retval;
@@ -300,6 +298,8 @@
 
   static octave_call_stack *instance;
 
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
   int do_current_line (void) const;
 
   int do_current_column (void) const;