octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

ISO C++ (partial) replacement for libio stream:scan


From: Mumit Khan
Subject: ISO C++ (partial) replacement for libio stream:scan
Date: Sun, 4 Feb 2001 02:57:05 -0600 (CST)

Forgot to include this in my 6-part patchset. 

First cut at a working sscanf/fscanf functionality in C++ library
with libstdc++-v2/libio scan/form extension. The correct way to
fix this problem of course is either (1) write a complete scan and
form implementation based on libio, or (2) write a stream manipulator
that translates print-style format to stream style (preferred). Octave
makes (2) easy by pre-sorting all the format codes in advance.

Very rudimentary, partial implementation just so I could get some work
done and run the tests. Now passes all the tests with newer compilers.

Patch against Octave CVS 2001-02-02.

Haven't tested anything other than trivial format specifiers, and haven't
even considered character classes yet.

Regards,
Mumit

Forgot to include this in my 6-part patchset. 

First cut at a working sscanf/fscanf functionality in C++ library
with libstdc++-v2/libio scan/form extension. The correct way to
fix this problem of course is either (1) write a complete scan and
form implementation based on libio, or (2) write a stream manipulator
that translates print-style format to stream style (preferred). Octave
makes (2) easy by pre-sorting all the format codes in advance.

Very rudimentary, partial implementation just so I could get some work
done and run the tests. Now passes all the tests with newer compilers.

Patch against Octave CVS 2001-02-02.

2001-02-03  Mumit Khan  <address@hidden>

        * oct-stream.cc (octave_scan): Implement, and specialize for
        char*. Delete the old template instantiations.
        (BEGIN_S_CONVERSION): Use strings instead of ostrstreambuf.
        (octave_base_stream::do_scanf): Pass correct parameter to
        do_scan_conv.

Index: src/oct-stream.cc
===================================================================
RCS file: /home/khan/src/math/CVSROOT/octave-dev/src/oct-stream.cc,v
retrieving revision 1.2
diff -u -3 -p -r1.2 oct-stream.cc
--- src/oct-stream.cc   2001/02/04 00:45:03     1.2
+++ src/oct-stream.cc   2001/02/04 08:48:35
@@ -1068,46 +1068,40 @@ octave_base_stream::read (const Matrix& 
 
 #define OCTAVE_SCAN(is, fmt, arg) is.scan ((fmt).text, arg)
 
-#else
+#else /* __GNUG__ && !CXX_ISO_COMPLIANT_LIBRARY */
 
 #define OCTAVE_SCAN(is, fmt, arg) octave_scan (is, fmt, arg)
 
 template <class T>
 std::istream&
-octave_scan (std::istream& is, const scanf_format_elt& fmt, T valptr)
+octave_scan (std::istream& is, const scanf_format_elt& fmt, T* valptr)
 {
-  // Someone else who cares will have to fix this code.  I refuse to
-  // waste my time working on it when a reasonable alternative like
-  // istream::scan exists in the GNU iostream library.  --jwe
-
-  error ("formatted input only works when Octave is compiled with G++");
-
-  is.setstate (std::ios::failbit);
-
+  T& ref = *valptr;
+  switch (fmt.type)
+    {
+    case 'o':
+      is >> std::oct >> ref;
+      break;
+    case 'x':
+      is >> std::hex >> ref;
+      break;
+    default:
+      is >> ref;
+      break;
+    }
   return is;
 }
-
-template std::istream&
-octave_scan (std::istream&, const scanf_format_elt&, char*);
-
-template std::istream&
-octave_scan (std::istream&, const scanf_format_elt&, int*);
 
-template std::istream&
-octave_scan (std::istream&, const scanf_format_elt&, long int*);
-
-template std::istream&
-octave_scan (std::istream&, const scanf_format_elt&, short int*);
-
-#if 0
-template std::istream&
-octave_scan (std::istream&, const scanf_format_elt&, float*);
-#endif
-
-template std::istream&
-octave_scan (std::istream&, const scanf_format_elt&, double*);
+// Note that this specialization is only used for reading characters, not 
+// character strings. See BEGIN_S_CONVERSION for details.
+template<>
+std::istream&
+octave_scan<> (std::istream& is, const scanf_format_elt& fmt, char* valptr)
+{
+  return is >> valptr;
+}
 
-#endif
+#endif /* __GNUG__ && !CXX_ISO_COMPLIANT_LIBRARY */
 
 template <class T>
 void
@@ -1254,25 +1248,10 @@ do_scanf_conv (std::istream&, const scan
        } \
       else \
        { \
-         std::ostrstream buf; \
- \
-         int c = EOF; \
- \
-         while (is && (c = is.get ()) != EOF && isspace (c)) \
-           /* skip leading whitespace */; \
- \
-         if (is && c != EOF) \
-           buf << (char) c; \
- \
-         while (is && (c = is.get ()) != EOF && ! isspace (c)) \
-           buf << (char) c; \
- \
-         if (isspace (c)) \
-           is.putback (c); \
- \
-         buf << std::ends; \
- \
-         tmp = buf.str (); \
+         std::string buf; \
+         is >> std::ws >> buf; \
+         tmp = new char[buf.length() + 1]; \
+         strcpy (tmp, buf.c_str()); \
        } \
     } \
   while (0)
@@ -1512,7 +1491,7 @@ octave_base_stream::do_scanf (scanf_form
                      case 'h':
                        {
                          short int tmp;
-                         do_scanf_conv (is, fmt, &tmp, mval, data,
+                         do_scanf_conv (is, *elt, &tmp, mval, data,
                                         data_index, conversion_count,
                                         nr, max_size, discard);
                        }
@@ -1521,7 +1500,7 @@ octave_base_stream::do_scanf (scanf_form
                      case 'l':
                        {
                          long int tmp;
-                         do_scanf_conv (is, fmt, &tmp, mval, data,
+                         do_scanf_conv (is, *elt, &tmp, mval, data,
                                         data_index, conversion_count,
                                         nr, max_size, discard);
                        }
@@ -1530,7 +1509,7 @@ octave_base_stream::do_scanf (scanf_form
                      default:
                        {
                          int tmp;
-                         do_scanf_conv (is, fmt, &tmp, mval, data,
+                         do_scanf_conv (is, *elt, &tmp, mval, data,
                                         data_index, conversion_count,
                                         nr, max_size, discard);
                        }
@@ -1543,7 +1522,7 @@ octave_base_stream::do_scanf (scanf_form
                  {
                    double tmp;
 
-                   do_scanf_conv (is, fmt, &tmp, mval, data,
+                   do_scanf_conv (is, *elt, &tmp, mval, data,
                                   data_index, conversion_count,
                                   nr, max_size, discard);
                  }

reply via email to

[Prev in Thread] Current Thread [Next in Thread]