changeset 444:ba637cc5c5f3

[project @ 1994-06-02 17:15:07 by jwe]
author jwe
date Thu, 02 Jun 1994 17:15:07 +0000
parents 25570b554bca
children 98a165f6e6c5
files src/builtins.cc src/file-io.cc src/file-io.h src/g-builtins.cc src/g-builtins.h src/sysdep.cc src/sysdep.h src/utils.h
diffstat 8 files changed, 577 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/src/builtins.cc	Thu Jun 02 17:05:58 1994 +0000
+++ b/src/builtins.cc	Thu Jun 02 17:15:07 1994 +0000
@@ -39,6 +39,7 @@
 #include "tree.h"
 #include "help.h"
 #include "pager.h"
+#include "sysdep.h"
 #include "mappers.h"
 #include "variables.h"
 #include "user-prefs.h"
@@ -304,6 +305,16 @@
   { "fclose", 2, 1, builtin_fclose,
     "fclose (\"filename\" or filenum): close a file", },
 
+  { "feof", 3, 1, builtin_feof,
+    "eof = feof (filenum)\n\n\
+ Returns a non zero eof for an end of file condition for the\n\
+ file specified by \"filenum\" from fopen", },
+
+  { "ferror", 3, 1, builtin_ferror,
+    "error = ferror (filenum)\n\n\
+ Returns a non zero \"error\" for an error condition on the\n\
+ file specified by \"filenum\" from fopen", },
+
   { "feval", -1, 1, builtin_feval,
     "feval (\"name\", args, ...): evaluate first argument as function", },
 
@@ -336,6 +347,17 @@
   { "fprintf", -1, 1, builtin_fprintf,
     "fprintf (\"file\", \"fmt\", ...)", },
 
+  { "fread", 3, 1, builtin_fread,
+    "[data, count] = fread (filenum, size, \"precision\")\n\n\
+ Reads data in binary form of type \"precision\" from a file.\n\n\
+ filenum   : file number from fopen\n\
+ size      : size specification for the Data matrix\n\
+ precision : type of data to read, valid types are\n\n\
+               'char',   'schar', 'short',  'int',  'long', 'float'\n\
+               'double', 'uchar', 'ushort', 'uint', 'ulong'\n\n\
+ data      : matrix in which the data is stored\n\
+ count     : number of elements read", },
+
   { "freport", 1, 1, builtin_freport,
     "freport (): list open files and their status", },
 
@@ -390,6 +412,16 @@
   { "ftell", 2, 1, builtin_ftell,
     "position = ftell (\"filename\" or filenum): returns the current file position", },
 
+  { "fwrite", 3, 1, builtin_fwrite,
+    "count = fwrite (filenum, Data, \"precision\")\n\n\
+ Writes data to a file in binary form of size \"precision\"\n\n\
+ filenum   : file number from fopen\n\
+ Data      : matrix of elements to be written\n\
+ precision : type of data to read, valid types are\n\n\
+               'char',   'schar', 'short',  'int',  'long', 'float'\n\
+               'double', 'uchar', 'ushort', 'uint', 'ulong'\n\n\
+ count     : number of elements written", },
+
   { "getenv", 2, 1, builtin_getenv,
     "getenv (\"string\"): get environment variable values", },
 
@@ -397,7 +429,6 @@
     "G = givens (x, y): compute orthogonal matrix G = [c s; -conj (s) c]\n\
       such that G [x; y] = [*; 0]  (x, y scalars)\n\n\
       [c, s] = givens (x, y) returns the (c, s) values themselves.", },
-  
 
   { "hess", 2, 2, builtin_hess,
     "[P, H] = hess (A) or H = hess (A): Hessenberg decomposition", },
@@ -898,50 +929,17 @@
   tmp =  new tree_constant (2.0);
   bind_builtin_variable ("stderr", tmp, 1, 1);
 
-// If using 1.0 / 0.0 doesn't work, you might also try using a very
-// large constant like 1.0e100000.
-
-#if defined (HAVE_ISINF) || defined (HAVE_FINITE)
-#ifdef linux
-  double tmp_inf = HUGE_VAL;
-#else
-  double tmp_inf = 1.0 / 0.0;
-#endif
-
-  tmp = new tree_constant (tmp_inf);
+  tmp = new tree_constant (octave_Inf);
   bind_builtin_variable ("Inf", tmp, 1, 1);
 
-  tmp = new tree_constant (tmp_inf);
+  tmp = new tree_constant (octave_Inf);
   bind_builtin_variable ("inf", tmp, 1, 1);
 
-#else
-
-// This is sort of cheesy, but what can we do, other than blowing it
-// off completely, or writing an entire IEEE emulation package?
-
-  tmp = new tree_constant (DBL_MAX);
-  bind_builtin_variable ("Inf", tmp, 1, 1);
-
-  tmp = new tree_constant (DBL_MAX);
-  bind_builtin_variable ("inf", tmp, 1, 1);
-#endif
-
-// If 0.0 / 0.0 fails to produce a NaN, you might also try
-// something like Inf / Inf.
-
-#if defined (HAVE_ISNAN)
-#ifdef linux
-  double tmp_nan = NAN;
-#else
-  double tmp_nan = 0.0 / 0.0;
-#endif
-
-  tmp = new tree_constant (tmp_nan);
+  tmp = new tree_constant (octave_NaN);
   bind_builtin_variable ("NaN", tmp, 1, 1);
 
-  tmp = new tree_constant (tmp_nan);
+  tmp = new tree_constant (octave_NaN);
   bind_builtin_variable ("nan", tmp, 1, 1);
-#endif
 }
 
 int
--- a/src/file-io.cc	Thu Jun 02 17:05:58 1994 +0000
+++ b/src/file-io.cc	Thu Jun 02 17:15:07 1994 +0000
@@ -31,10 +31,13 @@
 #include <unistd.h>
 #include <string.h>
 #include <stdio.h>
+#include <errno.h>
 #include <stdlib.h>
 #include <strstream.h>
 #include <ctype.h>
 
+#include "Matrix.h"
+
 #include "statdefs.h"
 #include "file-io.h"
 #include "input.h"
@@ -43,6 +46,8 @@
 #include "error.h"
 #include "utils.h"
 #include "pager.h"
+#include "sysdep.h"
+#include "mappers.h"
 
 // keeps a count of how many files are open and in the file list
 static int file_count = 0;
@@ -66,6 +71,9 @@
   FILE *fptr (void) const;
   const char *mode (void) const;
 
+  int eof (void) const;
+  int error (void) const;
+
  private:
   int file_number;
   char *file_name;
@@ -159,6 +167,10 @@
   file_count = 3;
 }
 
+/*
+ * Given a file name or number, return a pointer to the corresponding
+ * open file.  If the file has not already been opened, return NULL.
+ */
 Pix
 return_valid_file (const tree_constant& arg)
 {
@@ -1196,6 +1208,382 @@
 }
 
 /*
+ * Find out how many elements are left.
+ *
+ *   size is the size of the elements
+ *   nr is the number of rows or columns in the matrix
+ */
+static long
+get_whats_left (FILE *fptr, int size, int nn)
+{
+  long curr_pos = ftell (fptr);
+
+  fseek (fptr, 0, SEEK_END);
+  long end_of_file = ftell (fptr);
+
+  fseek (fptr, end_of_file, SEEK_SET);
+
+  long len = end_of_file - curr_pos;
+
+  long num_items = len / size / nn;
+
+  if (len > num_items * size * nn)
+    num_items++;
+
+  return num_items;
+}
+
+static void
+get_size_conv (const char *preci, int& size, Matrix::conversion& conv,
+	       const char *warn)
+{
+// Get type and number of bytes per element to read.
+
+  char *prec = strdup (preci);
+  char *ip = prec;
+
+  while (*ip > 0)
+    {
+      tolower (*ip);
+      ip++;
+    }
+
+  if (strcmp (prec, "uchar") == 0)
+    {
+      size = 1;
+      conv = Matrix::CNV_UCHAR;
+    }
+  else if (strcmp (prec, "char") == 0)
+    {
+      size = 1;
+      conv = Matrix::CNV_CHAR;
+    }
+  else if (strcmp (prec, "schar") == 0)
+    {
+      size = 1;
+      conv = Matrix::CNV_CHAR;
+// Some systems may need this??
+// size = 1;
+// conv = CNV_SCHAR;
+    }
+  else if (strcmp (prec, "short") == 0)
+    {
+      size = 2;
+      conv = Matrix::CNV_SHORT;
+    }
+  else if (strcmp (prec, "ushort") == 0)
+    {
+      size = 2;
+      conv = Matrix::CNV_USHORT;
+    }
+  else if (strcmp (prec, "int") == 0)
+    {
+      size = 4;
+      conv = Matrix::CNV_INT;
+    }
+  else if (strcmp (prec, "uint") == 0)
+    {
+      size = 4;
+      conv = Matrix::CNV_UINT;
+    }
+  else if (strcmp (prec, "long") == 0)
+    {
+      size = 4;
+      conv = Matrix::CNV_LONG;
+    }
+  else if (strcmp (prec, "ulong") == 0)
+    {
+      size = 4;
+      conv = Matrix::CNV_ULONG;
+    }
+  else if (strcmp (prec, "float") == 0)
+    {
+      size = 4;
+      conv = Matrix::CNV_FLOAT;
+    }
+  else if (strcmp (prec, "double") == 0)
+    {
+      size = 8;
+      conv = Matrix::CNV_DOUBLE;
+    }
+  else
+    {
+      error ("%s: precision: \'%s\' unknown", warn, prec);
+      size = -1;
+      conv = Matrix::CNV_UNKNOWN;
+    }
+
+  delete [] prec;
+
+  return;
+}
+
+/*
+ * Read binary data from a file.
+ *
+ *   [data, count] = fread (fid, size, 'precision')
+ *
+ *     fid       : the file id from fopen
+ *     size      : the size of the matrix or vector or scaler to read
+ *
+ *                 n	  : reads n elements of a column vector
+ *                 inf	  : reads to the end of file (default)
+ *                 [m, n] : reads enough elements to fill the matrix
+ *                          the number of columns can be inf
+ *
+ *     precision : type of the element.  Can be:
+ *
+ *                 char, uchar, schar, short, ushort, int, uint,
+ *                 long, ulong, float, double
+ *
+ *                 Default  is uchar.
+ *
+ *     data	 : output data
+ *     count	 : number of elements read
+ */
+tree_constant *
+fread_internal (const tree_constant *args, int nargin, int nargout)
+{
+  tree_constant *retval = NULL_TREE_CONST;
+
+  Pix p = file_io_get_file (args[1], "r", "fread");
+
+  if (p == (Pix) NULL)
+    return retval;
+
+// Get type and number of bytes per element to read.
+  char *prec = "uchar";
+  if (nargin > 3)
+    {
+      if (args[3].is_string_type ())
+	prec = args[3].string_value ();
+      else
+	{
+	  error ("fread: precision must be a specified as a string");
+	  return retval;
+	}
+    }
+
+  int size;
+  Matrix::conversion conv;
+  get_size_conv (prec, size, conv, "fread");
+  if (size < 0)
+    return retval;
+
+// Get file info.
+  file_info file = file_list (p);
+  FILE * fptr = file.fptr ();
+
+// Set up matrix to read into.  If specified in arguments use that
+// number, otherwise read everyting left in file.
+
+  double dnr = 1.0;
+  double dnc = 1.0;
+  int nr = 1;
+  int nc = 1;
+
+  if (nargin > 2)
+    {
+// tree_constant tmpa = args[2].make_numeric (); // ??
+
+      if (args[2].is_scalar_type ())
+	{
+	  tree_constant tmpa = args[2].make_numeric ();
+
+	  dnr = 1.0;
+	  dnc = tmpa.double_value ();
+	}
+      else if (args[2].is_matrix_type ())
+	{
+// tree_constant tmpa = args[2].make_numeric (); // ??
+      Matrix tmpm = args[2].to_matrix ();
+      nr = tmpm.rows ();
+      nc = tmpm.columns ();
+
+      if(nr != 1 || nc > 2)
+	{
+	  error ("fread: Illegal size specification\n");
+	  print_usage ("fread");
+	  return retval;
+	}
+      dnr = tmpm.elem (0, 0);
+      dnc = tmpm.elem (0, 1);
+    }
+
+    if ((xisinf (dnr)) && (xisinf (dnc)))
+      {
+	error ("fread: number of rows and columns cannot both be infinite\n");
+	return retval;
+      }
+
+    if (xisinf (dnr))
+      {
+	nc = NINT (dnc);
+	nr = get_whats_left (fptr, size, nc);
+      }
+    else if (xisinf (dnc))
+      {
+	nr = NINT (dnr);
+	nc = get_whats_left (fptr, size, nr);
+      }
+    else
+      {
+	nr = NINT (dnr);
+	nc = NINT (dnc);
+      }
+    }
+  else
+    {
+// No size parameter, read what's left of the file.
+      nr = 1;
+      nc = get_whats_left (fptr, size, nr);
+    }
+
+  Matrix m (nr, nc, octave_NaN);
+
+// Read data.
+
+  int count = m.read (fptr, size, conv);
+
+  if (nargout > 1)
+    {
+      retval = new tree_constant[3];
+      retval[1] = tree_constant ((double) count);
+    }
+  else
+    retval = new tree_constant[2];
+
+  retval[0] = tree_constant (m);
+
+  return retval;
+}
+
+/*
+ * Write binary data to a file.
+ *
+ *   count = fwrite (fid, data, 'precision')
+ *
+ *    fid	: file id from fopen
+ *    Data	: data to be written
+ *    precision	: type of output element.  Can be:
+ *
+ *                char, uchar, schar, short, ushort, int, uint,
+ *                long, float, double
+ *
+ *                 Default is uchar.
+ *
+ *    count     : the number of elements written
+ */
+tree_constant *
+fwrite_internal (const tree_constant *args, int nargin, int nargout)
+{
+  tree_constant *retval = NULL_TREE_CONST;
+
+  Pix p = file_io_get_file (args[1], "a+", "fwrite");
+
+  if (p == (Pix) NULL)
+    return retval;
+
+// Get type and number of bytes per element to read.
+  char *prec = "uchar";
+  if (nargin > 3)
+    {
+      if (args[3].is_string_type ())
+	prec = args[3].string_value ();
+      else
+	{
+	  error ("fwrite: precision must be a specified as a string");
+	  return retval;
+	}
+    }
+
+  int size;
+  Matrix::conversion conv;
+  get_size_conv(prec, size, conv, "fwrite");
+  if (size < 0)
+    return retval;
+
+// Get file info.
+  file_info file = file_list (p);
+
+// Write the matrix data.
+  tree_constant tmpa = args[2].make_numeric ();
+
+  Matrix tmpm = tmpa.to_matrix ();
+
+  int count = tmpm.write (file.fptr(), size, conv);
+
+  retval = new tree_constant[2];
+  retval[0] = tree_constant ((double) count);
+
+  return retval;
+}
+
+/*
+ * Check for an EOF condition on a file opened by fopen.
+ *
+ *   eof = feof (fid)
+ *
+ *     fid : file id from fopen
+ *     eof : non zero for an end of file condition
+ */
+tree_constant *
+feof_internal (const tree_constant *args, int nargin, int nargout)
+{
+  tree_constant *retval = NULL_TREE_CONST;
+
+// Get file info.
+  Pix p = return_valid_file (args[1]);
+
+  if (p == (Pix) NULL)
+    return retval;
+
+  file_info file = file_list (p);
+
+  retval = new tree_constant[2];
+  retval[0] = tree_constant (feof (file.fptr ()));
+
+  return retval;
+}
+
+/*
+ * Check for an error condition on a file opened by fopen.
+ *
+ *   [message, errnum] = ferror (fid)
+ *
+ *     fid     : file id from fopen
+ *     message : system error message
+ *     errnum  : error number
+ */
+tree_constant *
+ferror_internal (const tree_constant *args, int nargin, int nargout)
+{
+  tree_constant *retval = NULL_TREE_CONST;
+
+// Get file info.
+  Pix p = return_valid_file (args[1]);
+
+  if (p == (Pix) NULL)
+    return retval;
+
+  file_info file = file_list (p);
+
+  int ierr = ferror (file.fptr ());
+
+  if (nargout > 1)
+    {
+      retval = new tree_constant[3];
+      retval[1] = tree_constant ((double) ierr);
+    }
+  else
+    retval = new tree_constant[2];
+
+  retval[0] = tree_constant (strsave (strerror (ierr)));
+
+  return retval;
+}
+
+/*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
 ;;; page-delimiter: "^/\\*" ***
--- a/src/file-io.h	Thu Jun 02 17:05:58 1994 +0000
+++ b/src/file-io.h	Thu Jun 02 17:15:07 1994 +0000
@@ -33,13 +33,21 @@
 extern Pix return_valid_file (const tree_constant& arg);
 
 extern tree_constant *fclose_internal (const tree_constant *args);
+extern tree_constant *feof_internal (const tree_constant *args,
+				     int nargin, int nargout);
+extern tree_constant *ferror_internal (const tree_constant *args,
+                                       int nargin, int nargout);
 extern tree_constant *fflush_internal (const tree_constant *args);
 extern tree_constant *fgets_internal (const tree_constant *args, int nargout);
 extern tree_constant *fopen_internal (const tree_constant *args);
+extern tree_constant *fread_internal (const tree_constant *args,
+				      int nargin, int nargout);
 extern tree_constant *freport_internal (void);
 extern tree_constant *frewind_internal (const tree_constant *args);
 extern tree_constant *fseek_internal (const tree_constant *args, int nargin);
 extern tree_constant *ftell_internal (const tree_constant *args);
+extern tree_constant *fwrite_internal (const tree_constant *args,
+				       int nargin, int nargout);
 
 extern void initialize_file_io (void);
 
--- a/src/g-builtins.cc	Thu Jun 02 17:05:58 1994 +0000
+++ b/src/g-builtins.cc	Thu Jun 02 17:15:07 1994 +0000
@@ -582,6 +582,38 @@
 }
 
 /*
+ * Check file for EOF condition.
+ */
+tree_constant *
+builtin_feof (const tree_constant *args, int nargin, int nargout)
+{
+  tree_constant *retval = NULL_TREE_CONST;
+
+  if (nargin < 1)
+    print_usage ("feof");
+  else
+    retval = feof_internal (args, nargin, nargout);
+
+  return retval;
+}
+
+/*
+ * Check file for error condition.
+ */
+tree_constant *
+builtin_ferror (const tree_constant *args, int nargin, int nargout)
+{
+  tree_constant *retval = NULL_TREE_CONST;
+
+  if (nargin < 1)
+    print_usage ("ferror");
+  else
+    retval = ferror_internal (args, nargin, nargout);
+
+  return retval;
+}
+
+/*
  * Evaluate first argument as a function.
  */
 tree_constant *
@@ -598,7 +630,7 @@
 }
 
 /*
- * Flushing output to a file
+ * Flushing output to a file.
  */
 tree_constant *
 builtin_fflush (const tree_constant *args, int nargin, int nargout)
@@ -614,7 +646,7 @@
 }
 
 /*
- * Fast Fourier Transform
+ * Fast Fourier Transform.
  */
 tree_constant *
 builtin_fft (const tree_constant *args, int nargin, int nargout)
@@ -634,7 +666,7 @@
 }
 
 /*
- * get a string from a file
+ * Get a string from a file.
  */
 tree_constant *
 builtin_fgets (const tree_constant *args, int nargin, int nargout)
@@ -721,7 +753,23 @@
 }
 
 /*
- * rewind a file
+ * Read binary data from a file.
+ */
+tree_constant *
+builtin_fread (const tree_constant *args, int nargin, int nargout)
+{
+  tree_constant *retval = NULL_TREE_CONST;
+
+  if (nargin < 2)
+    print_usage ("fread");
+  else
+    retval = fread_internal (args, nargin, nargout);
+
+  return retval;
+}
+
+/*
+ * Rewind a file.
  */
 tree_constant *
 builtin_frewind (const tree_constant *args, int nargin, int nargout)
@@ -737,7 +785,7 @@
 }
 
 /*
- * report on open files
+ * Report on open files.
  */
 tree_constant *
 builtin_freport (const tree_constant *args, int nargin, int nargout)
@@ -769,7 +817,7 @@
 }
 
 /*
- * seek a point in a file for reading and/or writing 
+ * Seek a point in a file for reading and/or writing.
  */
 tree_constant *
 builtin_fseek (const tree_constant *args, int nargin, int nargout)
@@ -851,7 +899,7 @@
 }
 
 /*
- * tell current position of file
+ * Tell current position of file.
  */
 tree_constant *
 builtin_ftell (const tree_constant *args, int nargin, int nargout)
@@ -867,6 +915,22 @@
 }
 
 /*
+ * Write binary data to a file.
+ */
+tree_constant *
+builtin_fwrite (const tree_constant *args, int nargin, int nargout)
+{
+  tree_constant *retval = NULL_TREE_CONST;
+
+  if (nargin < 3)
+    print_usage ("fwrite");
+  else
+    retval = fwrite_internal (args, nargin, nargout);
+
+  return retval;
+}
+
+/*
  * Get the value of an environment variable.
  */
 tree_constant *
@@ -890,7 +954,7 @@
 }
 
 /*
- * Inverse Fast Fourier Transform
+ * Inverse Fast Fourier Transform.
  */
 tree_constant *
 builtin_ifft (const tree_constant *args, int nargin, int nargout)
@@ -1721,7 +1785,7 @@
 }
 
 /*
- * Schur Decomposition
+ * Schur Decomposition.
  */
 tree_constant *
 builtin_schur (const tree_constant *args, int nargin, int nargout)
@@ -1738,7 +1802,7 @@
 }
 
 /*
- * Givens rotation
+ * Givens rotation.
  */
 tree_constant *
 builtin_givens (const tree_constant *args, int nargin, int nargout)
@@ -1754,7 +1818,7 @@
 }
 
 /*
- * Hessenberg Decomposition
+ * Hessenberg Decomposition.
  */
 tree_constant *
 builtin_hess (const tree_constant *args, int nargin, int nargout)
--- a/src/g-builtins.h	Thu Jun 02 17:05:58 1994 +0000
+++ b/src/g-builtins.h	Thu Jun 02 17:15:07 1994 +0000
@@ -58,6 +58,8 @@
 extern tree_constant *builtin_expm (const tree_constant *, int, int);
 extern tree_constant *builtin_eye (const tree_constant *, int, int);
 extern tree_constant *builtin_fclose (const tree_constant *, int, int);
+extern tree_constant *builtin_feof (const tree_constant *, int, int);
+extern tree_constant *builtin_ferror (const tree_constant *, int, int);
 extern tree_constant *builtin_feval (const tree_constant *, int, int);
 extern tree_constant *builtin_fflush (const tree_constant *, int, int);
 extern tree_constant *builtin_fft (const tree_constant *, int, int);
@@ -66,6 +68,7 @@
 extern tree_constant *builtin_flops (const tree_constant *, int, int);
 extern tree_constant *builtin_fopen (const tree_constant *, int, int);
 extern tree_constant *builtin_fprintf (const tree_constant *, int, int);
+extern tree_constant *builtin_fread (const tree_constant *, int, int);
 extern tree_constant *builtin_frewind (const tree_constant *, int, int);
 extern tree_constant *builtin_freport (const tree_constant *, int, int);
 extern tree_constant *builtin_fscanf (const tree_constant *, int, int);
@@ -75,6 +78,7 @@
 extern tree_constant *builtin_fsqp (const tree_constant *, int, int);
 extern tree_constant *builtin_fsqp_options (const tree_constant *, int, int);
 extern tree_constant *builtin_ftell (const tree_constant *, int, int);
+extern tree_constant *builtin_fwrite (const tree_constant *, int, int);
 extern tree_constant *builtin_getenv (const tree_constant *, int, int);
 extern tree_constant *builtin_givens (const tree_constant *, int, int);
 extern tree_constant *builtin_hess (const tree_constant *, int, int);
@@ -86,7 +90,8 @@
 extern tree_constant *builtin_keyboard (const tree_constant *, int, int);
 extern tree_constant *builtin_logm (const tree_constant *, int, int);
 extern tree_constant *builtin_lpsolve (const tree_constant *, int, int);
-extern tree_constant *builtin_lpsolve_options (const tree_constant *, int, int);
+extern tree_constant *builtin_lpsolve_options (const tree_constant *,
+					       int, int);
 extern tree_constant *builtin_lsode (const tree_constant *, int, int);
 extern tree_constant *builtin_lsode_options (const tree_constant *, int, int);
 extern tree_constant *builtin_lu (const tree_constant *, int, int);
--- a/src/sysdep.cc	Thu Jun 02 17:05:58 1994 +0000
+++ b/src/sysdep.cc	Thu Jun 02 17:15:07 1994 +0000
@@ -28,6 +28,13 @@
 #include <stdlib.h>
 
 #include "error.h"
+#include "sysdep.h"
+
+// Octave's idea of infinity.
+double octave_Inf;
+
+// Octave's idea of not a number.
+double octave_NaN;
 
 #if defined (__386BSD__) && defined (HAVE_FLOATINGPOINT_H)
 #include <floatingpoint.h>
@@ -58,6 +65,53 @@
 }
 #endif
 
+static void
+octave_ieee_init (void)
+{
+#if defined (HAVE_ISINF) || defined (HAVE_FINITE)
+
+// Some version of gcc on some old version of Linux used to crash when
+// trying to make Inf and NaN.
+
+#if defined (HAVE_INFINITY)
+  octave_Inf = infinity ();
+#else
+#ifdef linux
+  octave_Inf = HUGE_VAL;
+#else
+  double tmp = 1e+10;
+  octave_Inf = tmp;
+  for (;;)
+    {
+      octave_Inf *= 1e+10;
+      if (octave_Inf == tmp)
+	break;
+      tmp = octave_Inf;
+    }
+#endif
+#endif
+
+#if defined (HAVE_QUIET_NAN)
+  octave_NaN = quiet_nan ();
+#else
+#ifdef linux
+  octave_NaN = NAN;
+#else
+  octave_NaN = octave_Inf / octave_Inf;
+#endif
+#endif
+
+#else
+
+// This is sort of cheesy, but what can we do, other than blowing it
+// off completely, or writing an entire IEEE emulation package?
+
+  octave_Inf = DBL_MAX;
+  octave_NaN = DBL_MAX;
+
+#endif
+}
+
 void
 sysdep_init (void)
 {
@@ -69,6 +123,8 @@
 #ifdef NeXT
   NeXT_init ();
 #endif
+
+  octave_ieee_init ();
 }
 
 /*
--- a/src/sysdep.h	Thu Jun 02 17:05:58 1994 +0000
+++ b/src/sysdep.h	Thu Jun 02 17:15:07 1994 +0000
@@ -26,6 +26,12 @@
 
 extern void sysdep_init (void);
 
+// Octave's idea of infinity.
+extern double octave_Inf;
+
+// Octave's idea of not a number.
+extern double octave_NaN;
+
 #endif
 
 /*
--- a/src/utils.h	Thu Jun 02 17:05:58 1994 +0000
+++ b/src/utils.h	Thu Jun 02 17:15:07 1994 +0000
@@ -79,7 +79,8 @@
 extern int keyword_almost_match (const char **std, int *min_len,
 				 const char *s, int min_toks_to_match,
 				 int max_toks);
-extern char **get_fcn_file_names (int& ffl_len, const char *dir, int no_suffix);
+extern char **get_fcn_file_names (int& ffl_len, const char *dir,
+				  int no_suffix); 
 extern char **get_fcn_file_names (int& ffl_len, int no_suffix);
 extern int NINT (double x);
 extern double D_NINT (double x);