changeset 5465:d6163c0effd5

[project @ 2005-09-23 15:42:48 by jwe]
author jwe
date Fri, 23 Sep 2005 15:42:49 +0000
parents 9d0aab486882
children 6a4f87723932
files ChangeLog Makeconf.in aclocal.m4 configure.in scripts/miscellaneous/popen2.m src/ChangeLog src/Makefile.in src/oct-errno.cc.in src/oct-errno.h src/utils.cc
diffstat 10 files changed, 534 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2005-09-22  John W. Eaton  <jwe@octave.org>
 
+	* aclocal.m4 (OCTAVE_PROG_PERL): New macro.
+	* configure.in: Use it.
+	* Makeconf.in (PERL): Substitute it.
+
 	* config.guess, config.sub: Update from FSF sources.
 
 2005-09-19  David Bateman  <dbateman@free.fr>
--- a/Makeconf.in
+++ b/Makeconf.in
@@ -15,6 +15,8 @@
 SED = @SED@
 export SED
 
+PERL = @PERL@
+
 # A shell command to extract the version number from version.h.
 getversion = $(SED) -e '/OCTAVE_VERSION/!d' -e 's/.*"\(.*\)".*$$/\1/' -e q
 
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -807,6 +807,14 @@
 AC_SUBST([SED], $octave_cv_path_sed)
 AC_MSG_RESULT([$SED])
 ])
+dnl
+dnl Find Perl.
+dnl
+dnl OCTAVE_PROG_PERL
+AC_DEFUN(OCTAVE_PROG_PERL,
+[AC_CHECK_PROG(PERL, ${ac_tool_prefix}perl, ${ac_tool_prefix}perl, [])
+  AC_SUBST(PERL)
+])
 # OCTAVE_IEEE754_DATA_FORMAT
 # --------------
 # Check for IEEE 754 data format.
--- a/configure.in
+++ b/configure.in
@@ -29,7 +29,7 @@
 EXTERN_CXXFLAGS="$CXXFLAGS"
 
 AC_INIT
-AC_REVISION($Revision: 1.481 $)
+AC_REVISION($Revision: 1.482 $)
 AC_PREREQ(2.57)
 AC_CONFIG_SRCDIR([src/octave.cc])
 AC_CONFIG_HEADER(config.h)
@@ -1497,6 +1497,7 @@
 
 AC_PROG_AWK
 OCTAVE_PROG_SED
+OCTAVE_PROG_PERL
 
 OCTAVE_PROG_FLEX
 OCTAVE_PROG_BISON
--- a/scripts/miscellaneous/popen2.m
+++ b/scripts/miscellaneous/popen2.m
@@ -34,9 +34,19 @@
 ## [in, out, pid] = popen2 ("sort", "-nr");
 ## fputs (in, "these\nare\nsome\nstrings\n");
 ## fclose (in);
-## while (ischar (s = fgets (out)))
-##   fputs (stdout, s);
-## endwhile
+## EAGAIN = errno ("EAGAIN");
+## done = false;
+## do
+##   s = fgets (out);
+##   if (ischar (s))
+##     fputs (stdout, s);
+##   elseif (errno () == EAGAIN)
+##     sleep (0.1);
+##     fclear (out);
+##   else
+##     done = true;
+##   endif
+## until (done)
 ## fclose (out);
 ##      @print{} are
 ##      @print{} some
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,17 @@
+2005-09-23  John W. Eaton  <jwe@octave.org>
+
+	* utils.cc (Ferrno_list): New function.
+
+	* oct-errno.h, oct-errno.cc.in: New files.
+	* Makefile.in: Add them to the appropriate lists.
+	(oct-errno.cc): New rule.
+	($(OPT_HANDLERS)): Use $(PERL) instead of just perl.
+
+	* utils.cc: Include oct-errno.h.
+	(Ferrno): Rename from FERRNO.  Allow errno to be set.  Allow
+	lookups of errno codes by name and access to structure containing
+	all errno names and codes.
+
 2005-09-19  John W. Eaton  <jwe@octave.org>
 
 	* pt-bp.cc (tree_breakpoint::visit_index_expression):
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -95,7 +95,7 @@
 	error.h file-io.h fn-cache.h gripes.h help.h input.h \
 	lex.h load-save.h ls-hdf5.h ls-mat-ascii.h ls-mat4.h \
 	ls-mat5.h ls-oct-ascii.h ls-oct-binary.h ls-utils.h \
-	oct-fstrm.h oct-hist.h oct-iostrm.h oct-map.h oct-obj.h \
+	oct-errno.h oct-fstrm.h oct-hist.h oct-iostrm.h oct-map.h oct-obj.h \
 	oct-prcstrm.h oct-procbuf.h oct-stdstrm.h oct-stream.h zfstream.h \
 	oct-strstrm.h oct-lvalue.h oct.h octave.h ops.h pager.h \
 	parse.h pr-output.h procstream.h sighandlers.h siglist.h \
@@ -179,13 +179,15 @@
 
 EXTRAS := ov-base-int.cc ov-base-mat.cc ov-base-scalar.cc 
 
+EXTRA_OBJECTS := oct-errno.o octave.o builtins.o ops.o
+
 INCLUDES_FOR_INSTALL := $(INCLUDES) $(EXTRAS)
 
 OBJECTS_4 := $(notdir $(SOURCES))
 OBJECTS_3 := $(patsubst %.l, %.o, $(OBJECTS_4))
 OBJECTS_2 := $(patsubst %.y, %.o, $(OBJECTS_3))
 OBJECTS_1 := $(patsubst %.c, %.o, $(OBJECTS_2))
-OBJECTS := $(patsubst %.cc, %.o, $(OBJECTS_1)) octave.o builtins.o ops.o
+OBJECTS := $(patsubst %.cc, %.o, $(OBJECTS_1)) $(EXTRA_OBJECTS)
 
 ifeq ($(SHARED_LIBS), true)
   ifdef CXXPICFLAG
@@ -252,7 +254,7 @@
 
 DISTFILES = Makefile.in ChangeLog mkdefs mkops mkgendoc \
 	DOCSTRINGS mkbuiltins mk-oct-links \
-	defaults.h.in oct-conf.h.in octave.gperf oct-gperf.h \
+	defaults.h.in oct-conf.h.in oct-errno.cc.in octave.gperf oct-gperf.h \
 	octave.cc parse.cc lex.cc y.tab.h gplot.cc \
 	$(INCLUDES) $(DIST_SRC) $(OPT_HANDLERS) $(EXTRAS)
 
@@ -523,7 +525,7 @@
 
 $(OPT_HANDLERS) : %.cc : $(top_srcdir)/liboctave/%.in $(top_srcdir)/mk-opts.pl
 	@echo making $@ from $<
-	@perl $(top_srcdir)/mk-opts.pl --opt-handler-fcns $< > $@-t
+	@$(PERL) $(top_srcdir)/mk-opts.pl --opt-handler-fcns $< > $@-t
 	@$(top_srcdir)/move-if-change $@-t $@
 
 parse.cc : parse.y
@@ -543,6 +545,19 @@
 oct-conf.h: oct-conf.h.in ../Makeconf Makefile
 	@$(do-subst-config-vals)
 
+oct-errno.cc: oct-errno.cc.in ../Makeconf Makefile
+	@echo "making $@ from $<"
+	if test -n "$(PERL)"; then \
+	  $(PERL) -e 'foreach $$key (keys(%!)) { $$x .= "#if defined ($$key)\n    { \"$$key\", $$key, },\n#endif\n"; }; while (<>) { s/^ *\@SYSDEP_ERRNO_LIST\@/$$x/; print; }' $< > $@.t; \
+	else \
+	  $(SED) '/@SYSDEP_ERRNO_LIST@/D' $< > $@.t; \
+	fi
+	@if [ -s $@.t ]; then \
+	  $(top_srcdir)/move-if-change $@.t $@; \
+	else \
+	  exit 1; \
+	fi
+
 oct-gperf.h: octave.gperf
 	@echo "making $@ from $<"
 	@$(GPERF) -t -C -D -G -L C++ -Z octave_kw_hash $< > $@-t1 \
new file mode 100644
--- /dev/null
+++ b/src/oct-errno.cc.in
@@ -0,0 +1,346 @@
+// oct-errno.cc.in
+/*
+
+Copyright (C) 2005 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cerrno>
+
+#include "oct-errno.h"
+#include "oct-map.h"
+#include "error.h"
+
+octave_errno *octave_errno::instance = 0;
+
+octave_errno::octave_errno (void)
+{
+  struct errno_struct
+  {
+    const char *name;
+    const int value;
+  };
+
+  static errno_struct errno_codes[] =
+  {
+    // POSIX.
+
+#if defined (E2BIG)
+    { "E2BIG", E2BIG, },
+#endif
+#if defined (EACCES)
+    { "EACCES", EACCES, },
+#endif
+#if defined (EADDRINUSE)
+    { "EADDRINUSE", EADDRINUSE, },
+#endif
+#if defined (EADDRNOTAVAIL)
+    { "EADDRNOTAVAIL", EADDRNOTAVAIL, },
+#endif
+#if defined (EAFNOSUPPORT)
+    { "EAFNOSUPPORT", EAFNOSUPPORT, },
+#endif
+#if defined (EAGAIN)
+    { "EAGAIN", EAGAIN, },
+#endif
+#if defined (EALREADY)
+    { "EALREADY", EALREADY, },
+#endif
+#if defined (EBADF)
+    { "EBADF", EBADF, },
+#endif
+#if defined (EBUSY)
+    { "EBUSY", EBUSY, },
+#endif
+#if defined (ECHILD)
+    { "ECHILD", ECHILD, },
+#endif
+#if defined (ECONNABORTED)
+    { "ECONNABORTED", ECONNABORTED, },
+#endif
+#if defined (ECONNREFUSED)
+    { "ECONNREFUSED", ECONNREFUSED, },
+#endif
+#if defined (ECONNRESET)
+    { "ECONNRESET", ECONNRESET, },
+#endif
+#if defined (EDEADLK)
+    { "EDEADLK", EDEADLK, },
+#endif
+#if defined (EDESTADDRREQ)
+    { "EDESTADDRREQ", EDESTADDRREQ, },
+#endif
+#if defined (EDOM)
+    { "EDOM", EDOM, },
+#endif
+#if defined (EDQUOT)
+    { "EDQUOT", EDQUOT, },
+#endif
+#if defined (EEXIST)
+    { "EEXIST", EEXIST, },
+#endif
+#if defined (EFAULT)
+    { "EFAULT", EFAULT, },
+#endif
+#if defined (EFBIG)
+    { "EFBIG", EFBIG, },
+#endif
+#if defined (EHOSTDOWN)
+    { "EHOSTDOWN", EHOSTDOWN, },
+#endif
+#if defined (EHOSTUNREACH)
+    { "EHOSTUNREACH", EHOSTUNREACH, },
+#endif
+#if defined (EINPROGRESS)
+    { "EINPROGRESS", EINPROGRESS, },
+#endif
+#if defined (EINTR)
+    { "EINTR", EINTR, },
+#endif
+#if defined (EINVAL)
+    { "EINVAL", EINVAL, },
+#endif
+#if defined (EIO)
+    { "EIO", EIO, },
+#endif
+#if defined (EISCONN)
+    { "EISCONN", EISCONN, },
+#endif
+#if defined (EISDIR)
+    { "EISDIR", EISDIR, },
+#endif
+#if defined (ELOOP)
+    { "ELOOP", ELOOP, },
+#endif
+#if defined (EMFILE)
+    { "EMFILE", EMFILE, },
+#endif
+#if defined (EMLINK)
+    { "EMLINK", EMLINK, },
+#endif
+#if defined (EMSGSIZE)
+    { "EMSGSIZE", EMSGSIZE, },
+#endif
+#if defined (ENAMETOOLONG)
+    { "ENAMETOOLONG", ENAMETOOLONG, },
+#endif
+#if defined (ENETDOWN)
+    { "ENETDOWN", ENETDOWN, },
+#endif
+#if defined (ENETRESET)
+    { "ENETRESET", ENETRESET, },
+#endif
+#if defined (ENETUNREACH)
+    { "ENETUNREACH", ENETUNREACH, },
+#endif
+#if defined (ENFILE)
+    { "ENFILE", ENFILE, },
+#endif
+#if defined (ENOBUFS)
+    { "ENOBUFS", ENOBUFS, },
+#endif
+#if defined (ENODEV)
+    { "ENODEV", ENODEV, },
+#endif
+#if defined (ENOENT)
+    { "ENOENT", ENOENT, },
+#endif
+#if defined (ENOEXEC)
+    { "ENOEXEC", ENOEXEC, },
+#endif
+#if defined (ENOLCK)
+    { "ENOLCK", ENOLCK, },
+#endif
+#if defined (ENOMEM)
+    { "ENOMEM", ENOMEM, },
+#endif
+#if defined (ENOPROTOOPT)
+    { "ENOPROTOOPT", ENOPROTOOPT, },
+#endif
+#if defined (ENOSPC)
+    { "ENOSPC", ENOSPC, },
+#endif
+#if defined (ENOSYS)
+    { "ENOSYS", ENOSYS, },
+#endif
+#if defined (ENOTBLK)
+    { "ENOTBLK", ENOTBLK, },
+#endif
+#if defined (ENOTCONN)
+    { "ENOTCONN", ENOTCONN, },
+#endif
+#if defined (ENOTDIR)
+    { "ENOTDIR", ENOTDIR, },
+#endif
+#if defined (ENOTEMPTY)
+    { "ENOTEMPTY", ENOTEMPTY, },
+#endif
+#if defined (ENOTSOCK)
+    { "ENOTSOCK", ENOTSOCK, },
+#endif
+#if defined (ENOTTY)
+    { "ENOTTY", ENOTTY, },
+#endif
+#if defined (ENXIO)
+    { "ENXIO", ENXIO, },
+#endif
+#if defined (EOPNOTSUPP)
+    { "EOPNOTSUPP", EOPNOTSUPP, },
+#endif
+#if defined (EPERM)
+    { "EPERM", EPERM, },
+#endif
+#if defined (EPFNOSUPPORT)
+    { "EPFNOSUPPORT", EPFNOSUPPORT, },
+#endif
+#if defined (EPIPE)
+    { "EPIPE", EPIPE, },
+#endif
+#if defined (EPROTONOSUPPORT)
+    { "EPROTONOSUPPORT", EPROTONOSUPPORT, },
+#endif
+#if defined (EPROTOTYPE)
+    { "EPROTOTYPE", EPROTOTYPE, },
+#endif
+#if defined (ERANGE)
+    { "ERANGE", ERANGE, },
+#endif
+#if defined (EREMOTE)
+    { "EREMOTE", EREMOTE, },
+#endif
+#if defined (ERESTART)
+    { "ERESTART", ERESTART, },
+#endif
+#if defined (EROFS)
+    { "EROFS", EROFS, },
+#endif
+#if defined (ESHUTDOWN)
+    { "ESHUTDOWN", ESHUTDOWN, },
+#endif
+#if defined (ESOCKTNOSUPPORT)
+    { "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT, },
+#endif
+#if defined (ESPIPE)
+    { "ESPIPE", ESPIPE, },
+#endif
+#if defined (ESRCH)
+    { "ESRCH", ESRCH, },
+#endif
+#if defined (ESTALE)
+    { "ESTALE", ESTALE, },
+#endif
+#if defined (ETIMEDOUT)
+    { "ETIMEDOUT", ETIMEDOUT, },
+#endif
+#if defined (ETOOMANYREFS)
+    { "ETOOMANYREFS", ETOOMANYREFS, },
+#endif
+#if defined (ETXTBSY)
+    { "ETXTBSY", ETXTBSY, },
+#endif
+#if defined (EUSERS)
+    { "EUSERS", EUSERS, },
+#endif
+#if defined (EWOULDBLOCK)
+    { "EWOULDBLOCK", EWOULDBLOCK, },
+#endif
+#if defined (EXDEV)
+    { "EXDEV", EXDEV, },
+#endif
+
+    // Others (duplicates are OK).
+
+    @SYSDEP_ERRNO_LIST@
+
+    { 0, 0, },
+  };
+
+  // Stuff them all in a map for fast access.
+
+  errno_struct *ptr = errno_codes;
+
+  while (ptr->name)
+    {
+      errno_tbl[ptr->name] = ptr->value;
+      ptr++;
+    }
+}
+
+bool
+octave_errno::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    instance = new octave_errno ();
+
+  if (! instance)
+    {
+      ::error ("unable to create errno object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+int
+octave_errno::lookup (const std::string& name)
+{
+  return (instance_ok ()) ? instance->do_lookup (name) : -1;
+}
+
+Octave_map
+octave_errno::list (void)
+{
+  return (instance_ok ()) ? instance->do_list () : Octave_map ();
+}
+
+int
+octave_errno::do_lookup (const std::string& name)
+{
+  return (errno_tbl.find (name) != errno_tbl.end ()) ? errno_tbl[name] : -1;
+}
+
+Octave_map
+octave_errno::do_list (void)
+{
+  Octave_map retval;
+
+  for (std::map<std::string, int>::const_iterator p = errno_tbl.begin ();
+       p != errno_tbl.end ();
+       p++)
+    {
+      retval.assign (p->first, p->second);
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
new file mode 100644
--- /dev/null
+++ b/src/oct-errno.h
@@ -0,0 +1,77 @@
+// oct-errno.h.in
+/*
+
+Copyright (C) 2005 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+*/
+
+#if !defined (octave_errno_h)
+#define octave_errno_h 1
+
+#include <map>
+#include <string>
+
+#include "oct-map.h"
+
+class
+octave_errno
+{
+protected:
+
+  octave_errno (void);
+
+public:
+
+  ~octave_errno (void) { }
+
+  static bool instance_ok (void);
+
+  static int lookup (const std::string& name);
+
+  static Octave_map list (void);
+
+  static int get (void) { return errno; }
+
+  static int set (int val)
+  {
+    int retval = errno;
+    errno = val;
+    return retval;
+  }
+
+private:
+
+  std::map<std::string, int> errno_tbl;
+
+  static octave_errno *instance;
+
+  int do_lookup (const std::string& name);
+
+  Octave_map do_list (void);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -40,11 +40,6 @@
 #include <unistd.h>
 #endif
 
-// Include setjmp.h, not csetjmp since the latter might only define
-// the ANSI standard C interface.
-
-#include <setjmp.h>
-
 #include "quit.h"
 
 #include "dir-ops.h"
@@ -64,6 +59,7 @@
 #include "error.h"
 #include "gripes.h"
 #include "input.h"
+#include "oct-errno.h"
 #include "oct-hist.h"
 #include "oct-obj.h"
 #include "pager.h"
@@ -691,29 +687,65 @@
   return retval;
 }
 
-
-// #if 0
-
-// Octave could use some way to access the value of ERRNO, but this is
-// probably not the best interface, so don't depend on it...
-
-DEFUN (ERRNO, args, ,
+DEFUNX ("errno", Ferrno, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {@var{system_error_number}} errno ()\n\
-Return the current value of the system-dependent variable errno.\n\
+@deftypefn {Built-in Function} {@var{err} =} errno ()\n\
+@deftypefnx {Built-in Function} {@var{err} =} errno (@var{val})\n\
+@deftypefnx {Built-in Function} {@var{err} =} errno (@var{name})\n\
+Return the current value of the system-dependent variable errno,\n\
+set its value to @var{val} and return the previous value, or return\n\
+the named error code given @var{name} as a character string, or -1\n\
+if @var{name} is not found.\n\
 @end deftypefn")
 {
   octave_value retval;
 
-  if (args.length () == 0)
-    retval = errno;
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      if (args(0).is_string ())
+	{
+	  std::string nm = args(0).string_value ();
+
+	  if (! error_state)
+	    retval = octave_errno::lookup (nm);
+	  else
+	    error ("errno: expecting character string argument");
+	}
+      else
+	{
+	  int val = args(0).int_value ();
+
+	  if (! error_state)
+	    retval = octave_errno::set (val);
+	  else
+	    error ("errno: expecting integer argument");
+	}
+    }
+  else if (nargin == 0)
+    retval = octave_errno::get ();
   else
     print_usage ("errno");
 
   return retval;
 }
 
-// #endif
+DEFUN (errno_list, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} errno_list ()\n\
+Return a structure containing the system-dependent errno values.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 0)
+    retval = octave_errno::list ();
+  else
+    print_usage ("errno_list");
+
+  return retval;
+}
 
 static void
 warn_old_style_preference (bool val, const std::string& sval)