changeset 1960:285a7f683a4c

[project @ 1996-02-16 04:03:01 by jwe] Initial revision
author jwe
date Fri, 16 Feb 1996 04:03:01 +0000
parents 9fae6fc592f2
children 41ff3c38af7e
files liboctave/byte-swap.h liboctave/data-conv.cc liboctave/data-conv.h liboctave/mach-info.cc liboctave/mach-info.h
diffstat 5 files changed, 1008 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/liboctave/byte-swap.h
@@ -0,0 +1,97 @@
+// byte-swap.h                                            -*- C++ -*-
+/*
+
+Copyright (C) 1996 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, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if !defined (octave_byte_swap_h)
+#define octave_byte_swap_h 1
+
+static inline void
+swap_bytes (char *t, unsigned int i, unsigned int j)
+{
+  char tmp = t[i];
+  t[i] = t[j];
+  t[j] = tmp;
+}
+
+static inline void
+swap_2_bytes (char *t)
+{
+  swap_bytes (t, 0, 1);
+}
+
+static inline void
+swap_4_bytes (char *t)
+{
+  swap_bytes (t, 0, 3);
+  swap_bytes (t, 1, 2);
+}
+
+static inline void
+swap_8_bytes (char *t)
+{
+  swap_bytes (t, 0, 7);
+  swap_bytes (t, 1, 6);
+  swap_bytes (t, 2, 5);
+  swap_bytes (t, 3, 4);
+}
+
+static inline void
+swap_2_bytes (char *t, int len)
+{
+  char *ptr = t;
+  for (int i = 0; i < len; i++)
+    {
+      swap_2_bytes (ptr);
+      ptr += 2;
+    }
+}
+
+static inline void
+swap_4_bytes (char *t, int len)
+{
+  char *ptr = t;
+  for (int i = 0; i < len; i++)
+    {
+      swap_4_bytes (ptr);
+      ptr += 4;
+    }
+}
+
+static inline void
+swap_8_bytes (char *t, int len)
+{
+  char *ptr = t;
+  for (int i = 0; i < len; i++)
+    {
+      swap_8_bytes (ptr);
+      ptr += 8;
+    }
+}
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
new file mode 100644
--- /dev/null
+++ b/liboctave/data-conv.cc
@@ -0,0 +1,641 @@
+// data-conv.cc                                           -*- C++ -*-
+/*
+
+Copyright (C) 1996 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, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream.h>
+
+#include "byte-swap.h"
+#include "data-conv.h"
+#include "lo-error.h"
+
+#define swap_1_bytes(x, y)
+
+#define LS_DO_READ(TYPE,swap,data,size,len,stream) \
+  do \
+    { \
+      volatile TYPE *ptr = (TYPE *) data; \
+      stream.read ((TYPE *) ptr, size * len); \
+      if (swap) \
+        swap_ ## size ## _bytes ((char *) ptr, len); \
+      TYPE tmp = ptr[0]; \
+      for (int i = len - 1; i > 0; i--) \
+        data[i] = ptr[i]; \
+      data[0] = tmp; \
+    } \
+  while (0)
+
+// Have to use copy here to avoid writing over data accessed via
+// Matrix::data().
+
+#define LS_DO_WRITE(TYPE,data,size,len,stream) \
+  do \
+    { \
+      char tmp_type = (char) type; \
+      stream.write (&tmp_type, 1); \
+      TYPE *ptr = new TYPE [len]; \
+      for (int i = 0; i < len; i++) \
+        ptr[i] = (TYPE) data[i]; \
+      stream.write ((TYPE *) ptr, size * len); \
+      delete [] ptr ; \
+    } \
+  while (0)
+
+// Loading variables from files.
+
+static void
+gripe_unrecognized_float_fmt (void)
+{
+  (*current_liboctave_error_handler)
+    ("unrecognized floating point format requested");
+}
+
+static void
+gripe_data_conversion (const char *from, const char *to)
+{
+  (*current_liboctave_error_handler)
+    ("unable to convert from %s to %s format", from, to);
+}
+
+// But first, some data conversion routines.
+
+// Currently, we only handle conversions for the IEEE types.  To fix
+// that, make more of the following routines work.
+
+// XXX FIXME XXX -- assumes sizeof (Complex) == 8
+// XXX FIXME XXX -- assumes sizeof (double) == 8
+// XXX FIXME XXX -- assumes sizeof (float) == 4
+
+static void
+IEEE_big_double_to_IEEE_little_double (double *d, int len)
+{
+  swap_8_bytes ((char *) d, len);
+}
+
+static void
+VAX_D_double_to_IEEE_little_double (double * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX D float", "IEEE little endian format");
+}
+
+static void
+VAX_G_double_to_IEEE_little_double (double * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX G float", "IEEE little endian format");
+}
+
+static void
+Cray_to_IEEE_little_double (double * /* d */, int /* len */)
+{
+  gripe_data_conversion ("Cray", "IEEE little endian format");
+}
+
+static void
+IEEE_big_float_to_IEEE_little_float (float *d, int len)
+{
+  swap_4_bytes ((char *) d, len);
+}
+
+static void
+VAX_D_float_to_IEEE_little_float (float * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX D float", "IEEE little endian format");
+}
+
+static void
+VAX_G_float_to_IEEE_little_float (float * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX G float", "IEEE little endian format");
+}
+
+static void
+Cray_to_IEEE_little_float (float * /* d */, int /* len */)
+{
+  gripe_data_conversion ("Cray", "IEEE little endian format");
+}
+
+static void
+IEEE_little_double_to_IEEE_big_double (double *d, int len)
+{
+  swap_8_bytes ((char *) d, len);
+}
+
+static void
+VAX_D_double_to_IEEE_big_double (double * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX D float", "IEEE big endian format");
+}
+
+static void
+VAX_G_double_to_IEEE_big_double (double * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX G float", "IEEE big endian format");
+}
+
+static void
+Cray_to_IEEE_big_double (double * /* d */, int /* len */)
+{
+  gripe_data_conversion ("Cray", "IEEE big endian format");
+}
+
+static void
+IEEE_little_float_to_IEEE_big_float (float *d, int len)
+{
+  swap_4_bytes ((char *) d, len);
+}
+
+static void
+VAX_D_float_to_IEEE_big_float (float * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX D float", "IEEE big endian format");
+}
+
+static void
+VAX_G_float_to_IEEE_big_float (float * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX G float", "IEEE big endian format");
+}
+
+static void
+Cray_to_IEEE_big_float (float * /* d */, int /* len */)
+{
+  gripe_data_conversion ("Cray", "IEEE big endian format");
+}
+
+static void
+IEEE_little_double_to_VAX_D_double (double * /* d */, int /* len */)
+{
+  gripe_data_conversion ("IEEE little endian", "VAX D");
+}
+
+static void
+IEEE_big_double_to_VAX_D_double (double * /* d */, int /* len */)
+{
+  gripe_data_conversion ("IEEE big endian", "VAX D");
+}
+
+static void
+VAX_G_double_to_VAX_D_double (double * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX G float", "VAX D");
+}
+
+static void
+Cray_to_VAX_D_double (double * /* d */, int /* len */)
+{
+  gripe_data_conversion ("Cray", "VAX D");
+}
+
+static void
+IEEE_little_float_to_VAX_D_float (float * /* d */, int /* len */)
+{
+  gripe_data_conversion ("IEEE little endian", "VAX D");
+}
+
+static void
+IEEE_big_float_to_VAX_D_float (float * /* d */, int /* len */)
+{
+  gripe_data_conversion ("IEEE big endian", "VAX D");
+}
+
+static void
+VAX_G_float_to_VAX_D_float (float * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX G float", "VAX D");
+}
+
+static void
+Cray_to_VAX_D_float (float * /* d */, int /* len */)
+{
+  gripe_data_conversion ("Cray", "VAX D");
+}
+
+static void
+IEEE_little_double_to_VAX_G_double (double * /* d */, int /* len */)
+{
+  gripe_data_conversion ("IEEE little endian", "VAX G");
+}
+
+static void
+IEEE_big_double_to_VAX_G_double (double * /* d */, int /* len */)
+{
+  gripe_data_conversion ("IEEE big endian", "VAX G");
+}
+
+static void
+VAX_D_double_to_VAX_G_double (double * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX D float", "VAX G");
+}
+
+static void
+Cray_to_VAX_G_double (double * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX G float", "VAX G");
+}
+
+static void
+IEEE_little_float_to_VAX_G_float (float * /* d */, int /* len */)
+{
+  gripe_data_conversion ("IEEE little endian", "VAX G");
+}
+
+static void
+IEEE_big_float_to_VAX_G_float (float * /* d */, int /* len */)
+{
+  gripe_data_conversion ("IEEE big endian", "VAX G");
+}
+
+static void
+VAX_D_float_to_VAX_G_float (float * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX D float", "VAX G");
+}
+
+static void
+Cray_to_VAX_G_float (float * /* d */, int /* len */)
+{
+  gripe_data_conversion ("VAX G float", "VAX G");
+}
+
+void
+do_double_format_conversion (double *data, int len,
+			     floating_point_format fmt)
+{
+  switch (native_float_format)
+    {
+    case OCTAVE_IEEE_LITTLE:
+      switch (fmt)
+	{
+	case OCTAVE_IEEE_LITTLE:
+	  break;
+
+	case OCTAVE_IEEE_BIG:
+	  IEEE_big_double_to_IEEE_little_double (data, len);
+	  break;
+
+	case OCTAVE_VAX_D:
+	  VAX_D_double_to_IEEE_little_double (data, len);
+	  break;
+
+	case OCTAVE_VAX_G:
+	  VAX_G_double_to_IEEE_little_double (data, len);
+	  break;
+
+	case OCTAVE_CRAY:
+	  Cray_to_IEEE_little_double (data, len);
+	  break;
+
+	default:
+	  gripe_unrecognized_float_fmt ();
+	  break;
+	}
+      break;
+
+    case OCTAVE_IEEE_BIG:
+      switch (fmt)
+	{
+	case OCTAVE_IEEE_LITTLE:
+	  IEEE_little_double_to_IEEE_big_double (data, len);
+	  break;
+
+	case OCTAVE_IEEE_BIG:
+	  break;
+
+	case OCTAVE_VAX_D:
+	  VAX_D_double_to_IEEE_big_double (data, len);
+	  break;
+
+	case OCTAVE_VAX_G:
+	  VAX_G_double_to_IEEE_big_double (data, len);
+	  break;
+
+	case OCTAVE_CRAY:
+	  Cray_to_IEEE_big_double (data, len);
+	  break;
+
+	default:
+	  gripe_unrecognized_float_fmt ();
+	  break;
+	}
+      break;
+
+    case OCTAVE_VAX_D:
+      switch (fmt)
+	{
+	case OCTAVE_IEEE_LITTLE:
+	  IEEE_little_double_to_VAX_D_double (data, len);
+	  break;
+
+	case OCTAVE_IEEE_BIG:
+	  IEEE_big_double_to_VAX_D_double (data, len);
+	  break;
+
+	case OCTAVE_VAX_D:
+	  break;
+
+	case OCTAVE_VAX_G:
+	  VAX_G_double_to_VAX_D_double (data, len);
+	  break;
+
+	case OCTAVE_CRAY:
+	  Cray_to_VAX_D_double (data, len);
+	  break;
+
+	default:
+	  gripe_unrecognized_float_fmt ();
+	  break;
+	}
+      break;
+
+    case OCTAVE_VAX_G:
+      switch (fmt)
+	{
+	case OCTAVE_IEEE_LITTLE:
+	  IEEE_little_double_to_VAX_G_double (data, len);
+	  break;
+
+	case OCTAVE_IEEE_BIG:
+	  IEEE_big_double_to_VAX_G_double (data, len);
+	  break;
+
+	case OCTAVE_VAX_D:
+	  VAX_D_double_to_VAX_G_double (data, len);
+	  break;
+
+	case OCTAVE_VAX_G:
+	  break;
+
+	case OCTAVE_CRAY:
+	  Cray_to_VAX_G_double (data, len);
+	  break;
+
+	default:
+	  gripe_unrecognized_float_fmt ();
+	  break;
+	}
+      break;
+
+    default:
+      (*current_liboctave_error_handler)
+	("impossible state reached in file `%s' at line %d",
+	 __FILE__, __LINE__);
+      break;
+    }
+}
+
+void
+do_float_format_conversion (float *data, int len,
+			    floating_point_format fmt)
+{
+  switch (native_float_format)
+    {
+    case OCTAVE_IEEE_LITTLE:
+      switch (fmt)
+	{
+	case OCTAVE_IEEE_LITTLE:
+	  break;
+
+	case OCTAVE_IEEE_BIG:
+	  IEEE_big_float_to_IEEE_little_float (data, len);
+	  break;
+
+	case OCTAVE_VAX_D:
+	  VAX_D_float_to_IEEE_little_float (data, len);
+	  break;
+
+	case OCTAVE_VAX_G:
+	  VAX_G_float_to_IEEE_little_float (data, len);
+	  break;
+
+	case OCTAVE_CRAY:
+	  Cray_to_IEEE_little_float (data, len);
+	  break;
+
+	default:
+	  gripe_unrecognized_float_fmt ();
+	  break;
+	}
+      break;
+
+    case OCTAVE_IEEE_BIG:
+      switch (fmt)
+	{
+	case OCTAVE_IEEE_LITTLE:
+	  IEEE_little_float_to_IEEE_big_float (data, len);
+	  break;
+
+	case OCTAVE_IEEE_BIG:
+	  break;
+
+	case OCTAVE_VAX_D:
+	  VAX_D_float_to_IEEE_big_float (data, len);
+	  break;
+
+	case OCTAVE_VAX_G:
+	  VAX_G_float_to_IEEE_big_float (data, len);
+	  break;
+
+	case OCTAVE_CRAY:
+	  Cray_to_IEEE_big_float (data, len);
+	  break;
+
+	default:
+	  gripe_unrecognized_float_fmt ();
+	  break;
+	}
+      break;
+
+    case OCTAVE_VAX_D:
+      switch (fmt)
+	{
+	case OCTAVE_IEEE_LITTLE:
+	  IEEE_little_float_to_VAX_D_float (data, len);
+	  break;
+
+	case OCTAVE_IEEE_BIG:
+	  IEEE_big_float_to_VAX_D_float (data, len);
+	  break;
+
+	case OCTAVE_VAX_D:
+	  break;
+
+	case OCTAVE_VAX_G:
+	  VAX_G_float_to_VAX_D_float (data, len);
+	  break;
+
+	case OCTAVE_CRAY:
+	  Cray_to_VAX_D_float (data, len);
+	  break;
+
+	default:
+	  gripe_unrecognized_float_fmt ();
+	  break;
+	}
+      break;
+
+    case OCTAVE_VAX_G:
+      switch (fmt)
+	{
+	case OCTAVE_IEEE_LITTLE:
+	  IEEE_little_float_to_VAX_G_float (data, len);
+	  break;
+
+	case OCTAVE_IEEE_BIG:
+	  IEEE_big_float_to_VAX_G_float (data, len);
+	  break;
+
+	case OCTAVE_VAX_D:
+	  VAX_D_float_to_VAX_G_float (data, len);
+	  break;
+
+	case OCTAVE_VAX_G:
+	  break;
+
+	case OCTAVE_CRAY:
+	  Cray_to_VAX_G_float (data, len);
+	  break;
+
+	default:
+	  gripe_unrecognized_float_fmt ();
+	  break;
+	}
+      break;
+
+    default:
+      (*current_liboctave_error_handler)
+	("impossible state reached in file `%s' at line %d",
+	 __FILE__, __LINE__);
+      break;
+    }
+}
+
+void
+read_doubles (istream& is, double *data, save_type type, int len,
+	      int swap, floating_point_format fmt)
+{
+  switch (type)
+    {
+    case LS_U_CHAR:
+      LS_DO_READ (unsigned char, swap, data, 1, len, is);
+      break;
+
+    case LS_U_SHORT:
+      LS_DO_READ (unsigned TWO_BYTE_INT, swap, data, 2, len, is);
+      break;
+
+    case LS_U_INT:
+      LS_DO_READ (unsigned FOUR_BYTE_INT, swap, data, 4, len, is);
+      break;
+
+    case LS_CHAR:
+      LS_DO_READ (signed char, swap, data, 1, len, is);
+      break;
+
+    case LS_SHORT:
+      LS_DO_READ (TWO_BYTE_INT, swap, data, 2, len, is);
+      break;
+
+    case LS_INT:
+      LS_DO_READ (FOUR_BYTE_INT, swap, data, 4, len, is);
+      break;
+
+    case LS_FLOAT:
+      {
+	volatile float *ptr = (float *) data;
+	is.read (data, 4 * len);
+	do_float_format_conversion ((float *) data, len, fmt);
+	float tmp = ptr[0];
+	for (int i = len - 1; i > 0; i--)
+	  data[i] = ptr[i];
+	data[0] = tmp;
+      }
+      break;
+
+    case LS_DOUBLE:
+      is.read (data, 8 * len);
+      do_double_format_conversion (data, len, fmt);
+      break;
+
+    default:
+      is.clear (ios::failbit|is.rdstate ());
+      break;
+    }
+}
+
+void
+write_doubles (ostream& os, const double *data, save_type type, int len)
+{
+  switch (type)
+    {
+    case LS_U_CHAR:
+      LS_DO_WRITE (unsigned char, data, 1, len, os);
+      break;
+
+    case LS_U_SHORT:
+      LS_DO_WRITE (unsigned TWO_BYTE_INT, data, 2, len, os);
+      break;
+
+    case LS_U_INT:
+      LS_DO_WRITE (unsigned FOUR_BYTE_INT, data, 4, len, os);
+      break;
+
+    case LS_CHAR:
+      LS_DO_WRITE (signed char, data, 1, len, os);
+      break;
+
+    case LS_SHORT:
+      LS_DO_WRITE (TWO_BYTE_INT, data, 2, len, os);
+      break;
+
+    case LS_INT:
+      LS_DO_WRITE (FOUR_BYTE_INT, data, 4, len, os);
+      break;
+
+    case LS_FLOAT:
+      LS_DO_WRITE (float, data, 4, len, os);
+      break;
+
+    case LS_DOUBLE:
+      {
+	char tmp_type = (char) type;
+	os.write (&tmp_type, 1);
+	os.write (data, 8 * len);
+      }
+      break;
+
+    default:
+      (*current_liboctave_error_handler)
+	("unrecognized data format requested");
+      break;
+    }
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
new file mode 100644
--- /dev/null
+++ b/liboctave/data-conv.h
@@ -0,0 +1,84 @@
+// data-conv.h                                            -*- C++ -*-
+/*
+
+Copyright (C) 1996 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, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if !defined (octave_data_conv_h)
+#define octave_data_conv_h 1
+
+#include <climits>
+
+#include "float-fmt.h"
+
+// Not all of the following are currently used.
+
+#if CHAR_BIT != 8
+#error "CHAR_BIT is not 8!"
+#endif
+
+#if SIZEOF_SHORT == 2
+#define TWO_BYTE_INT short
+#elif SIZEOF_INT == 2
+#define TWO_BYTE_INT int
+#else
+#error "No 2 byte integer type found!"
+#endif
+
+#if SIZEOF_INT == 4
+#define FOUR_BYTE_INT int
+#elif SIZEOF_LONG == 4
+#define FOUR_BYTE_INT long
+#else
+#error "No 4 byte integer type found!"
+#endif
+
+enum save_type
+  {
+    LS_U_CHAR,
+    LS_U_SHORT,
+    LS_U_INT,
+    LS_CHAR,
+    LS_SHORT,
+    LS_INT,
+    LS_FLOAT,
+    LS_DOUBLE,
+  };
+
+extern void
+do_double_format_conversion (double *data, int len, floating_point_format fmt);
+
+extern void
+do_float_format_conversion (float *data, int len, floating_point_format fmt);
+
+extern void
+read_doubles (istream& is, double *data, save_type type, int len,
+	      int swap, floating_point_format fmt);
+extern void
+write_doubles (ostream& os, const double *data, save_type type, int len);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
new file mode 100644
--- /dev/null
+++ b/liboctave/mach-info.cc
@@ -0,0 +1,134 @@
+// float-fmt.cc                                           -*- C++ -*-
+/*
+
+Copyright (C) 1996 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, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "f77-fcn.h"
+#include "float-fmt.h"
+
+extern "C"
+{
+  double F77_FCN (d1mach, D1MACH) (const int&);
+}
+
+// The floating point format on this system.
+floating_point_format native_float_format = OCTAVE_UNKNOWN_FLT_FMT;
+
+union equiv
+{
+  double d;
+  int i[2];
+};
+
+struct
+float_params
+{
+  floating_point_format fp_fmt;
+  equiv fp_par[4];
+};
+
+#define INIT_FLT_PAR(fp, fmt, sm1, sm2, lrg1, lrg2, rt1, rt2, dv1, dv2) \
+  do \
+    { \
+      fp.fp_fmt = (fmt); \
+      fp.fp_par[0].i[0] = (sm1);  fp.fp_par[0].i[1] = (sm2); \
+      fp.fp_par[1].i[0] = (lrg1); fp.fp_par[1].i[1] = (lrg2); \
+      fp.fp_par[2].i[0] = (rt1);  fp.fp_par[2].i[1] = (rt2); \
+      fp.fp_par[3].i[0] = (dv1);  fp.fp_par[3].i[1] = (dv2); \
+    } \
+  while (0)
+
+static int
+equiv_compare (const equiv *std, const equiv *v, int len)
+{
+  int i;
+  for (i = 0; i < len; i++)
+    if (v[i].i[0] != std[i].i[0] || v[i].i[1] != std[i].i[1])
+      return 0;
+  return 1;
+}
+
+int
+float_format_init (void)
+{
+  float_params fp[5];
+
+  INIT_FLT_PAR (fp[0], OCTAVE_IEEE_BIG,
+		   1048576,  0,
+		2146435071, -1,
+		1017118720,  0,
+		1018167296,  0);
+
+  INIT_FLT_PAR (fp[1], OCTAVE_IEEE_LITTLE,
+		 0,    1048576,
+		-1, 2146435071,
+		 0, 1017118720,
+		 0, 1018167296);
+
+  INIT_FLT_PAR (fp[2], OCTAVE_VAX_D,
+		   128,  0,
+		-32769, -1,
+		  9344,  0,
+		  9344,  0);
+
+  INIT_FLT_PAR (fp[3], OCTAVE_VAX_G,
+		    16,  0,
+		-32769, -1,
+		 15552,  0,
+		 15552,  0);
+
+  INIT_FLT_PAR (fp[4], OCTAVE_UNKNOWN_FLT_FMT,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0);
+
+  equiv mach_fp_par[4];
+
+  mach_fp_par[0].d = F77_FCN (d1mach, D1MACH) (1);
+  mach_fp_par[1].d = F77_FCN (d1mach, D1MACH) (2);
+  mach_fp_par[2].d = F77_FCN (d1mach, D1MACH) (3);
+  mach_fp_par[3].d = F77_FCN (d1mach, D1MACH) (4);
+
+  int i = 0;
+  do
+    {
+      if (equiv_compare (fp[i].fp_par, mach_fp_par, 4))
+	{
+	  native_float_format = fp[i].fp_fmt;
+	  break;
+	}
+    }
+  while (fp[++i].fp_fmt != OCTAVE_UNKNOWN_FLT_FMT);
+
+  return (native_float_format != OCTAVE_UNKNOWN_FLT_FMT);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
new file mode 100644
--- /dev/null
+++ b/liboctave/mach-info.h
@@ -0,0 +1,52 @@
+// float-fmt.h                                            -*- C++ -*-
+/*
+
+Copyright (C) 1996 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, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if !defined (octave_float_fmt_h)
+#define octave_float_fmt_h 1
+
+enum floating_point_format
+  {
+    OCTAVE_IEEE_LITTLE,
+    OCTAVE_IEEE_BIG,
+    OCTAVE_VAX_D,
+    OCTAVE_VAX_G,
+    OCTAVE_CRAY,
+    OCTAVE_UNKNOWN_FLT_FMT
+  };
+
+// The floating point format on this system.
+extern floating_point_format native_float_format;
+
+// Initializes the value of native_float_format.  Maybe this should be
+// done automatically using a class with a static member.  Hmm...
+extern int float_format_init (void);
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
+