changeset 17552:d07d59cc8775

move unwind-protect to liboctave * liboctave/util/action-container.h, liboctave/util/unwind-prot.cc, liboctave/util/unwind-prot.h: Move here from libinterp/corefcn. * unwind-prot.cc (unwind_protect_safe::gripe_exception): Use current_liboctave_error_handler to handle error message. * libinterp/corefcn/module.mk, liboctave/util/module.mk: Update file lists.
author John W. Eaton <jwe@octave.org>
date Thu, 03 Oct 2013 12:31:48 -0400
parents 8fca0bbdd4c1
children 2d01e20abd85
files libinterp/corefcn/action-container.h libinterp/corefcn/module.mk libinterp/corefcn/unwind-prot.cc libinterp/corefcn/unwind-prot.h liboctave/util/action-container.h liboctave/util/module.mk liboctave/util/unwind-prot.cc liboctave/util/unwind-prot.h
diffstat 8 files changed, 528 insertions(+), 523 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/action-container.h	Thu Oct 03 12:15:00 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,341 +0,0 @@
-/*
-
-Copyright (C) 1993-2012 John W. Eaton
-Copyright (C) 2009-2010 VZLU Prague
-
-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/>.
-
-*/
-
-#if !defined (octave_action_container_h)
-#define octave_action_container_h 1
-
-// This class allows registering actions in a list for later
-// execution, either explicitly or when the container goes out of
-// scope.
-
-// FIXME -- is there a better name for this class?
-
-class
-action_container
-{
-public:
-
-  // A generic unwind_protect element. Knows how to run itself and
-  // discard itself.  Also, contains a pointer to the next element.
-  class elem
-  {
-  public:
-    elem (void) { }
-
-    virtual void run (void) { }
-
-    virtual ~elem (void) { }
-
-    friend class action_container;
-
-  private:
-
-    // No copying!
-
-    elem (const elem&);
-
-    elem& operator = (const elem&);
-  };
-
-  // An element that merely runs a void (*)(void) function.
-
-  class fcn_elem : public elem
-  {
-  public:
-    fcn_elem (void (*fptr) (void))
-      : e_fptr (fptr) { }
-
-    void run (void) { e_fptr (); }
-
-  private:
-    void (*e_fptr) (void);
-  };
-
-  // An element that stores a variable of type T along with a void (*) (T)
-  // function pointer, and calls the function with the parameter.
-
-  template <class T>
-  class fcn_arg_elem : public elem
-  {
-  public:
-    fcn_arg_elem (void (*fcn) (T), T arg)
-      : e_fcn (fcn), e_arg (arg) { }
-
-    void run (void) { e_fcn (e_arg); }
-
-  private:
-
-    // No copying!
-
-    fcn_arg_elem (const fcn_arg_elem&);
-
-    fcn_arg_elem& operator = (const fcn_arg_elem&);
-
-    void (*e_fcn) (T);
-    T e_arg;
-  };
-
-  // An element that stores a variable of type T along with a
-  // void (*) (const T&) function pointer, and calls the function with
-  // the parameter.
-
-  template <class T>
-  class fcn_crefarg_elem : public elem
-  {
-  public:
-    fcn_crefarg_elem (void (*fcn) (const T&), const T& arg)
-      : e_fcn (fcn), e_arg (arg) { }
-
-    void run (void) { e_fcn (e_arg); }
-
-  private:
-    void (*e_fcn) (const T&);
-    T e_arg;
-  };
-
-  // An element for calling a member function.
-
-  template <class T>
-  class method_elem : public elem
-  {
-  public:
-    method_elem (T *obj, void (T::*method) (void))
-      : e_obj (obj), e_method (method) { }
-
-    void run (void) { (e_obj->*e_method) (); }
-
-  private:
-
-    T *e_obj;
-    void (T::*e_method) (void);
-
-    // No copying!
-
-    method_elem (const method_elem&);
-
-    method_elem operator = (const method_elem&);
-  };
-
-  // An element for calling a member function with a single argument
-
-  template <class T, class A>
-  class method_arg_elem : public elem
-  {
-  public:
-    method_arg_elem (T *obj, void (T::*method) (A), A arg)
-      : e_obj (obj), e_method (method), e_arg (arg) { }
-
-    void run (void) { (e_obj->*e_method) (e_arg); }
-
-  private:
-
-    T *e_obj;
-    void (T::*e_method) (A);
-    A e_arg;
-
-    // No copying!
-
-    method_arg_elem (const method_arg_elem&);
-
-    method_arg_elem operator = (const method_arg_elem&);
-  };
-
-  // An element for calling a member function with a single argument
-
-  template <class T, class A>
-  class method_crefarg_elem : public elem
-  {
-  public:
-    method_crefarg_elem (T *obj, void (T::*method) (const A&), const A& arg)
-      : e_obj (obj), e_method (method), e_arg (arg) { }
-
-    void run (void) { (e_obj->*e_method) (e_arg); }
-
-  private:
-
-    T *e_obj;
-    void (T::*e_method) (const A&);
-    A e_arg;
-
-    // No copying!
-
-    method_crefarg_elem (const method_crefarg_elem&);
-
-    method_crefarg_elem operator = (const method_crefarg_elem&);
-  };
-
-  // An element that stores arbitrary variable, and restores it.
-
-  template <class T>
-  class restore_var_elem : public elem
-  {
-  public:
-    restore_var_elem (T& ref, const T& val)
-      : e_ptr (&ref), e_val (val) { }
-
-    void run (void) { *e_ptr = e_val; }
-
-  private:
-
-    // No copying!
-
-    restore_var_elem (const restore_var_elem&);
-
-    restore_var_elem& operator = (const restore_var_elem&);
-
-    T *e_ptr, e_val;
-  };
-
-  // Deletes a class allocated using new.
-
-  template <class T>
-  class delete_ptr_elem : public elem
-  {
-  public:
-    delete_ptr_elem (T *ptr)
-      : e_ptr (ptr) { }
-
-    void run (void) { delete e_ptr; }
-
-  private:
-
-    T *e_ptr;
-
-    // No copying!
-
-    delete_ptr_elem (const delete_ptr_elem&);
-
-    delete_ptr_elem operator = (const delete_ptr_elem&);
-  };
-
-  action_container (void) { }
-
-  virtual ~action_container (void) { }
-
-  virtual void add (elem *new_elem) = 0;
-
-  // Call to void func (void).
-  void add_fcn (void (*fcn) (void))
-  {
-    add (new fcn_elem (fcn));
-  }
-
-  // Call to void func (T).
-  template <class T>
-  void add_fcn (void (*action) (T), T val)
-  {
-    add (new fcn_arg_elem<T> (action, val));
-  }
-
-  // Call to void func (const T&).
-  template <class T>
-  void add_fcn (void (*action) (const T&), const T& val)
-  {
-    add (new fcn_crefarg_elem<T> (action, val));
-  }
-
-  // Call to T::method (void).
-  template <class T>
-  void add_method (T *obj, void (T::*method) (void))
-  {
-    add (new method_elem<T> (obj, method));
-  }
-
-  // Call to T::method (A).
-  template <class T, class A>
-  void add_method (T *obj, void (T::*method) (A), A arg)
-  {
-    add (new method_arg_elem<T, A> (obj, method, arg));
-  }
-
-  // Call to T::method (const A&).
-  template <class T, class A>
-  void add_method (T *obj, void (T::*method) (const A&), const A& arg)
-  {
-    add (new method_crefarg_elem<T, A> (obj, method, arg));
-  }
-
-  // Call to delete (T*).
-
-  template <class T>
-  void add_delete (T *obj)
-  {
-    add (new delete_ptr_elem<T> (obj));
-  }
-
-  // Protect any variable.
-  template <class T>
-  void protect_var (T& var)
-  {
-    add (new restore_var_elem<T> (var, var));
-  }
-
-  // Protect any variable, value given.
-  template <class T>
-  void protect_var (T& var, const T& val)
-  {
-    add (new restore_var_elem<T> (var, val));
-  }
-
-  operator bool (void) const { return ! empty (); }
-
-  virtual void run_first (void) = 0;
-
-  void run (size_t num)
-  {
-    if (num > size ())
-      num = size ();
-
-    for (size_t i = 0; i < num; i++)
-      run_first ();
-  }
-
-  void run (void) { run (size ()); }
-
-  virtual void discard_first (void) = 0;
-
-  void discard (size_t num)
-  {
-    if (num > size ())
-      num = size ();
-
-    for (size_t i = 0; i < num; i++)
-      discard_first ();
-  }
-
-  void discard (void) { discard (size ()); }
-
-  virtual size_t size (void) const = 0;
-
-  bool empty (void) const { return size () == 0; }
-
-private:
-
-  // No copying!
-
-  action_container (const action_container&);
-
-  action_container& operator = (const action_container&);
-};
-
-#endif
--- a/libinterp/corefcn/module.mk	Thu Oct 03 12:15:00 2013 -0400
+++ b/libinterp/corefcn/module.mk	Thu Oct 03 12:31:48 2013 -0400
@@ -44,7 +44,6 @@
 
 COREFCN_INC = \
   corefcn/Cell.h \
-  corefcn/action-container.h \
   corefcn/c-file-ptr-stream.h \
   corefcn/comment-list.h \
   corefcn/cutils.h \
@@ -108,7 +107,6 @@
   corefcn/toplev.h \
   corefcn/txt-eng-ft.h \
   corefcn/txt-eng.h \
-  corefcn/unwind-prot.h \
   corefcn/utils.h \
   corefcn/variables.h \
   corefcn/workspace-element.h \
@@ -256,7 +254,6 @@
   corefcn/txt-eng.cc \
   corefcn/txt-eng-ft.cc \
   corefcn/typecast.cc \
-  corefcn/unwind-prot.cc \
   corefcn/utils.cc \
   corefcn/variables.cc \
   corefcn/xdiv.cc \
--- a/libinterp/corefcn/unwind-prot.cc	Thu Oct 03 12:15:00 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
-
-Copyright (C) 1993-2012 John W. Eaton
-Copyright (C) 2009 VZLU Prague
-
-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 "error.h"
-#include "unwind-prot.h"
-
-void unwind_protect_safe::gripe_exception (void)
-{
-  // FIXME: can this throw an exception?
-  error ("internal: unhandled exception in unwind_protect handler");
-}
--- a/libinterp/corefcn/unwind-prot.h	Thu Oct 03 12:15:00 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-/*
-
-Copyright (C) 1993-2012 John W. Eaton
-Copyright (C) 2009-2010 VZLU Prague
-
-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/>.
-
-*/
-
-#if !defined (octave_unwind_prot_h)
-#define octave_unwind_prot_h 1
-
-#include <stack>
-#include <memory>
-
-#include "action-container.h"
-
-class
-OCTINTERP_API
-unwind_protect : public action_container
-{
-public:
-
-  unwind_protect (void) : lifo () { }
-
-  // Destructor should not raise an exception, so all actions
-  // registered should be exception-safe (but setting error_state is
-  // allowed). If you're not sure, see unwind_protect_safe.
-
-  ~unwind_protect (void) { run (); }
-
-  virtual void add (elem *new_elem)
-  {
-    lifo.push (new_elem);
-  }
-
-  void add (void (*fcn) (void *), void *ptr = 0) GCC_ATTR_DEPRECATED
-  {
-    add (new fcn_arg_elem<void *> (fcn, ptr));
-  }
-
-  operator bool (void) const { return ! empty (); }
-
-  void run_top (void) GCC_ATTR_DEPRECATED { run_first (); }
-
-  void run_first (void)
-  {
-    if (! empty ())
-      {
-        // No leak on exception!
-        std::auto_ptr<elem> ptr (lifo.top ());
-        lifo.pop ();
-        ptr->run ();
-      }
-  }
-
-  void run_top (int num) GCC_ATTR_DEPRECATED { run (num); }
-
-  void discard_top (void) GCC_ATTR_DEPRECATED { discard_first (); }
-
-  void discard_first (void)
-  {
-    if (! empty ())
-      {
-        elem *ptr = lifo.top ();
-        lifo.pop ();
-        delete ptr;
-      }
-  }
-
-  void discard_top (int num) GCC_ATTR_DEPRECATED { discard (num); }
-
-  size_t size (void) const { return lifo.size (); }
-
-protected:
-
-  std::stack<elem *> lifo;
-
-private:
-
-  // No copying!
-
-  unwind_protect (const unwind_protect&);
-
-  unwind_protect& operator = (const unwind_protect&);
-};
-
-// Like unwind_protect, but this one will guard against the
-// possibility of seeing an exception (or interrupt) in the cleanup
-// actions. Not that we can do much about it, but at least we won't
-// crash.
-
-class
-OCTINTERP_API
-unwind_protect_safe : public unwind_protect
-{
-private:
-
-  static void gripe_exception (void);
-
-public:
-
-  unwind_protect_safe (void) : unwind_protect () { }
-
-  ~unwind_protect_safe (void)
-    {
-      while (! empty ())
-        {
-          try
-            {
-              run_first ();
-            }
-          catch (...) // Yes, the black hole. Remember we're in a dtor.
-            {
-              gripe_exception ();
-            }
-        }
-    }
-
-private:
-
-  // No copying!
-
-  unwind_protect_safe (const unwind_protect_safe&);
-
-  unwind_protect_safe& operator = (const unwind_protect_safe&);
-};
-
-#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/util/action-container.h	Thu Oct 03 12:31:48 2013 -0400
@@ -0,0 +1,341 @@
+/*
+
+Copyright (C) 1993-2012 John W. Eaton
+Copyright (C) 2009-2010 VZLU Prague
+
+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/>.
+
+*/
+
+#if !defined (octave_action_container_h)
+#define octave_action_container_h 1
+
+// This class allows registering actions in a list for later
+// execution, either explicitly or when the container goes out of
+// scope.
+
+// FIXME -- is there a better name for this class?
+
+class
+action_container
+{
+public:
+
+  // A generic unwind_protect element. Knows how to run itself and
+  // discard itself.  Also, contains a pointer to the next element.
+  class elem
+  {
+  public:
+    elem (void) { }
+
+    virtual void run (void) { }
+
+    virtual ~elem (void) { }
+
+    friend class action_container;
+
+  private:
+
+    // No copying!
+
+    elem (const elem&);
+
+    elem& operator = (const elem&);
+  };
+
+  // An element that merely runs a void (*)(void) function.
+
+  class fcn_elem : public elem
+  {
+  public:
+    fcn_elem (void (*fptr) (void))
+      : e_fptr (fptr) { }
+
+    void run (void) { e_fptr (); }
+
+  private:
+    void (*e_fptr) (void);
+  };
+
+  // An element that stores a variable of type T along with a void (*) (T)
+  // function pointer, and calls the function with the parameter.
+
+  template <class T>
+  class fcn_arg_elem : public elem
+  {
+  public:
+    fcn_arg_elem (void (*fcn) (T), T arg)
+      : e_fcn (fcn), e_arg (arg) { }
+
+    void run (void) { e_fcn (e_arg); }
+
+  private:
+
+    // No copying!
+
+    fcn_arg_elem (const fcn_arg_elem&);
+
+    fcn_arg_elem& operator = (const fcn_arg_elem&);
+
+    void (*e_fcn) (T);
+    T e_arg;
+  };
+
+  // An element that stores a variable of type T along with a
+  // void (*) (const T&) function pointer, and calls the function with
+  // the parameter.
+
+  template <class T>
+  class fcn_crefarg_elem : public elem
+  {
+  public:
+    fcn_crefarg_elem (void (*fcn) (const T&), const T& arg)
+      : e_fcn (fcn), e_arg (arg) { }
+
+    void run (void) { e_fcn (e_arg); }
+
+  private:
+    void (*e_fcn) (const T&);
+    T e_arg;
+  };
+
+  // An element for calling a member function.
+
+  template <class T>
+  class method_elem : public elem
+  {
+  public:
+    method_elem (T *obj, void (T::*method) (void))
+      : e_obj (obj), e_method (method) { }
+
+    void run (void) { (e_obj->*e_method) (); }
+
+  private:
+
+    T *e_obj;
+    void (T::*e_method) (void);
+
+    // No copying!
+
+    method_elem (const method_elem&);
+
+    method_elem operator = (const method_elem&);
+  };
+
+  // An element for calling a member function with a single argument
+
+  template <class T, class A>
+  class method_arg_elem : public elem
+  {
+  public:
+    method_arg_elem (T *obj, void (T::*method) (A), A arg)
+      : e_obj (obj), e_method (method), e_arg (arg) { }
+
+    void run (void) { (e_obj->*e_method) (e_arg); }
+
+  private:
+
+    T *e_obj;
+    void (T::*e_method) (A);
+    A e_arg;
+
+    // No copying!
+
+    method_arg_elem (const method_arg_elem&);
+
+    method_arg_elem operator = (const method_arg_elem&);
+  };
+
+  // An element for calling a member function with a single argument
+
+  template <class T, class A>
+  class method_crefarg_elem : public elem
+  {
+  public:
+    method_crefarg_elem (T *obj, void (T::*method) (const A&), const A& arg)
+      : e_obj (obj), e_method (method), e_arg (arg) { }
+
+    void run (void) { (e_obj->*e_method) (e_arg); }
+
+  private:
+
+    T *e_obj;
+    void (T::*e_method) (const A&);
+    A e_arg;
+
+    // No copying!
+
+    method_crefarg_elem (const method_crefarg_elem&);
+
+    method_crefarg_elem operator = (const method_crefarg_elem&);
+  };
+
+  // An element that stores arbitrary variable, and restores it.
+
+  template <class T>
+  class restore_var_elem : public elem
+  {
+  public:
+    restore_var_elem (T& ref, const T& val)
+      : e_ptr (&ref), e_val (val) { }
+
+    void run (void) { *e_ptr = e_val; }
+
+  private:
+
+    // No copying!
+
+    restore_var_elem (const restore_var_elem&);
+
+    restore_var_elem& operator = (const restore_var_elem&);
+
+    T *e_ptr, e_val;
+  };
+
+  // Deletes a class allocated using new.
+
+  template <class T>
+  class delete_ptr_elem : public elem
+  {
+  public:
+    delete_ptr_elem (T *ptr)
+      : e_ptr (ptr) { }
+
+    void run (void) { delete e_ptr; }
+
+  private:
+
+    T *e_ptr;
+
+    // No copying!
+
+    delete_ptr_elem (const delete_ptr_elem&);
+
+    delete_ptr_elem operator = (const delete_ptr_elem&);
+  };
+
+  action_container (void) { }
+
+  virtual ~action_container (void) { }
+
+  virtual void add (elem *new_elem) = 0;
+
+  // Call to void func (void).
+  void add_fcn (void (*fcn) (void))
+  {
+    add (new fcn_elem (fcn));
+  }
+
+  // Call to void func (T).
+  template <class T>
+  void add_fcn (void (*action) (T), T val)
+  {
+    add (new fcn_arg_elem<T> (action, val));
+  }
+
+  // Call to void func (const T&).
+  template <class T>
+  void add_fcn (void (*action) (const T&), const T& val)
+  {
+    add (new fcn_crefarg_elem<T> (action, val));
+  }
+
+  // Call to T::method (void).
+  template <class T>
+  void add_method (T *obj, void (T::*method) (void))
+  {
+    add (new method_elem<T> (obj, method));
+  }
+
+  // Call to T::method (A).
+  template <class T, class A>
+  void add_method (T *obj, void (T::*method) (A), A arg)
+  {
+    add (new method_arg_elem<T, A> (obj, method, arg));
+  }
+
+  // Call to T::method (const A&).
+  template <class T, class A>
+  void add_method (T *obj, void (T::*method) (const A&), const A& arg)
+  {
+    add (new method_crefarg_elem<T, A> (obj, method, arg));
+  }
+
+  // Call to delete (T*).
+
+  template <class T>
+  void add_delete (T *obj)
+  {
+    add (new delete_ptr_elem<T> (obj));
+  }
+
+  // Protect any variable.
+  template <class T>
+  void protect_var (T& var)
+  {
+    add (new restore_var_elem<T> (var, var));
+  }
+
+  // Protect any variable, value given.
+  template <class T>
+  void protect_var (T& var, const T& val)
+  {
+    add (new restore_var_elem<T> (var, val));
+  }
+
+  operator bool (void) const { return ! empty (); }
+
+  virtual void run_first (void) = 0;
+
+  void run (size_t num)
+  {
+    if (num > size ())
+      num = size ();
+
+    for (size_t i = 0; i < num; i++)
+      run_first ();
+  }
+
+  void run (void) { run (size ()); }
+
+  virtual void discard_first (void) = 0;
+
+  void discard (size_t num)
+  {
+    if (num > size ())
+      num = size ();
+
+    for (size_t i = 0; i < num; i++)
+      discard_first ();
+  }
+
+  void discard (void) { discard (size ()); }
+
+  virtual size_t size (void) const = 0;
+
+  bool empty (void) const { return size () == 0; }
+
+private:
+
+  // No copying!
+
+  action_container (const action_container&);
+
+  action_container& operator = (const action_container&);
+};
+
+#endif
--- a/liboctave/util/module.mk	Thu Oct 03 12:15:00 2013 -0400
+++ b/liboctave/util/module.mk	Thu Oct 03 12:31:48 2013 -0400
@@ -2,6 +2,7 @@
   util/module.mk
 
 UTIL_INC = \
+  util/action-container.h \
   util/base-list.h \
   util/byte-swap.h \
   util/caseless-str.h \
@@ -40,7 +41,8 @@
   util/sparse-util.h \
   util/statdefs.h \
   util/str-vec.h \
-  util/sun-utils.h 
+  util/sun-utils.h \
+  util/unwind-prot.cc
 
 UTIL_C_SRC = \
   util/f2c-main.c \
@@ -71,6 +73,7 @@
   util/sparse-sort.cc \
   util/sparse-util.cc \
   util/str-vec.cc \
+  util/unwind-prot.cc \
   $(UTIL_C_SRC)
 
 TEMPLATE_SRC += \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/util/unwind-prot.cc	Thu Oct 03 12:31:48 2013 -0400
@@ -0,0 +1,38 @@
+/*
+
+Copyright (C) 1993-2012 John W. Eaton
+Copyright (C) 2009 VZLU Prague
+
+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 "unwind-prot.h"
+
+void
+unwind_protect_safe::gripe_exception (void)
+{
+  // FIXME: can this throw an exception?
+
+  (*current_liboctave_error_handler)
+    ("internal: unhandled exception in unwind_protect handler");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/util/unwind-prot.h	Thu Oct 03 12:31:48 2013 -0400
@@ -0,0 +1,145 @@
+/*
+
+Copyright (C) 1993-2012 John W. Eaton
+Copyright (C) 2009-2010 VZLU Prague
+
+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/>.
+
+*/
+
+#if !defined (octave_unwind_prot_h)
+#define octave_unwind_prot_h 1
+
+#include <cstddef>
+
+#include <stack>
+#include <memory>
+
+#include "action-container.h"
+
+class
+OCTINTERP_API
+unwind_protect : public action_container
+{
+public:
+
+  unwind_protect (void) : lifo () { }
+
+  // Destructor should not raise an exception, so all actions
+  // registered should be exception-safe (but setting error_state is
+  // allowed). If you're not sure, see unwind_protect_safe.
+
+  ~unwind_protect (void) { run (); }
+
+  virtual void add (elem *new_elem)
+  {
+    lifo.push (new_elem);
+  }
+
+  void add (void (*fcn) (void *), void *ptr = 0) GCC_ATTR_DEPRECATED
+  {
+    add (new fcn_arg_elem<void *> (fcn, ptr));
+  }
+
+  operator bool (void) const { return ! empty (); }
+
+  void run_top (void) GCC_ATTR_DEPRECATED { run_first (); }
+
+  void run_first (void)
+  {
+    if (! empty ())
+      {
+        // No leak on exception!
+        std::auto_ptr<elem> ptr (lifo.top ());
+        lifo.pop ();
+        ptr->run ();
+      }
+  }
+
+  void run_top (int num) GCC_ATTR_DEPRECATED { run (num); }
+
+  void discard_top (void) GCC_ATTR_DEPRECATED { discard_first (); }
+
+  void discard_first (void)
+  {
+    if (! empty ())
+      {
+        elem *ptr = lifo.top ();
+        lifo.pop ();
+        delete ptr;
+      }
+  }
+
+  void discard_top (int num) GCC_ATTR_DEPRECATED { discard (num); }
+
+  size_t size (void) const { return lifo.size (); }
+
+protected:
+
+  std::stack<elem *> lifo;
+
+private:
+
+  // No copying!
+
+  unwind_protect (const unwind_protect&);
+
+  unwind_protect& operator = (const unwind_protect&);
+};
+
+// Like unwind_protect, but this one will guard against the
+// possibility of seeing an exception (or interrupt) in the cleanup
+// actions. Not that we can do much about it, but at least we won't
+// crash.
+
+class
+OCTINTERP_API
+unwind_protect_safe : public unwind_protect
+{
+private:
+
+  static void gripe_exception (void);
+
+public:
+
+  unwind_protect_safe (void) : unwind_protect () { }
+
+  ~unwind_protect_safe (void)
+    {
+      while (! empty ())
+        {
+          try
+            {
+              run_first ();
+            }
+          catch (...) // Yes, the black hole. Remember we're in a dtor.
+            {
+              gripe_exception ();
+            }
+        }
+    }
+
+private:
+
+  // No copying!
+
+  unwind_protect_safe (const unwind_protect_safe&);
+
+  unwind_protect_safe& operator = (const unwind_protect_safe&);
+};
+
+#endif