From bug-octave-request at bevo dot che dot wisc dot edu Fri Nov 5 10:52:48 1999 Subject: problems with file input from stdin From: "John W. Eaton" To: Vladimir Eltsov Cc: bug-octave at bevo dot che dot wisc dot edu Date: Fri, 5 Nov 1999 10:52:17 -0600 (CST) On 5-Nov-1999, Vladimir Eltsov wrote: | To: bug-octave at bevo dot che dot wisc dot edu | Cc: ve | Subject: problems with file input from stdin | | Bug report for Octave 2.1.20 configured for i686-pc-linux-gnu | | Description: | ----------- | | Octave treats stdin differently from other files even if stdin | is not a terminal. Sometimes it is just inconvinience for writing | filters as octave scripts (and I consider this scripting ability | as a great advantage of octave over matlab, scilab etc), sometimes | this leads to bugs. | | First, feof(stdin) always returns error. | Second, scanf has a bug (see below). | | Repeat-By: | --------- | | > cat testit | #!/opt/octave/bin/octave -qf | [a,k]=scanf("%f",Inf) | > echo "1 2 3" | testit | a = [](0x0) | k = 3 | > echo "1 2 3\n4 5 6" | testit | a = [](0x0) | k = 6 Here is a patch to try. With it, I see the following behavior: $ cat foo #! /home/jwe/build/octave/src/octave -qf feof (stdin) [a, k] = scanf ("%f", Inf) feof (stdin) $ echo "1 2 3" | ./foo ans = 0 a = 1 2 3 k = 3 ans = 1 Thanks, jwe 1999-11-05 John W. Eaton * oct-iostrm.h (octave_istream::eof, octave_ostream::eof): Provide implementation for these. * oct-stream.cc (octave_base_stream::do_scanf): The stdin stream is only special if we are interactive. (octave_base_stream::scanf): Ditto. (octave_base_stream::do_oscanf): Ditto. (octave_base_stream::oscanf): Ditto. Index: src/file-io.cc =================================================================== RCS file: /usr/local/cvsroot/octave/src/file-io.cc,v retrieving revision 1.110 diff -u -r1.110 file-io.cc --- file-io.cc 1999/11/05 08:11:58 1.110 +++ file-io.cc 1999/11/05 16:49:14 at @ -689,7 +689,7 @@ { octave_stream os = octave_stream_list::lookup (args(0), "fscanf"); - if (error_state) + if (! error_state) { if (args(1).is_string ()) { Index: src/oct-iostrm.cc =================================================================== RCS file: /usr/local/cvsroot/octave/src/oct-iostrm.cc,v retrieving revision 1.3 diff -u -r1.3 oct-iostrm.cc --- oct-iostrm.cc 1999/11/05 07:02:31 1.3 +++ oct-iostrm.cc 1999/11/05 16:49:14 at @ -60,10 +60,26 @@ ::error ("%s: invalid operation", stream_type ()); } +// Return non-zero if EOF has been reached on this stream. + +bool +octave_istream::eof (void) const +{ + return is && is->eof (); +} + octave_stream octave_istream::create (istream *arg, const string& nm) { return octave_stream (new octave_istream (arg, nm)); +} + +// Return non-zero if EOF has been reached on this stream. + +bool +octave_ostream::eof (void) const +{ + return os && os->eof (); } octave_stream Index: src/oct-iostrm.h =================================================================== RCS file: /usr/local/cvsroot/octave/src/oct-iostrm.h,v retrieving revision 1.7 diff -u -r1.7 oct-iostrm.h --- oct-iostrm.h 1999/11/05 07:02:31 1.7 +++ oct-iostrm.h 1999/11/05 16:49:14 at @ -88,6 +88,10 @@ static octave_stream create (istream *arg = 0, const string& nm = string ()); + // Return non-zero if EOF has been reached on this stream. + + bool eof (void) const; + istream *input_stream (void) { return is; } ostream *output_stream (void) { return 0; } at @ -120,6 +124,10 @@ static octave_stream create (ostream *arg, const string& nm = string ()); + + // Return non-zero if EOF has been reached on this stream. + + bool eof (void) const; istream *input_stream (void) { return 0; } Index: src/oct-stream.cc =================================================================== RCS file: /usr/local/cvsroot/octave/src/oct-stream.cc,v retrieving revision 1.36 diff -u -r1.36 oct-stream.cc --- oct-stream.cc 1999/11/05 08:11:59 1.36 +++ oct-stream.cc 1999/11/05 16:49:15 at @ -36,6 +36,7 @@ #include "str-vec.h" #include "error.h" +#include "input.h" #include "oct-stream.h" #include "oct-obj.h" #include "utils.h" at @ -1271,8 +1272,8 @@ is.clear (is.rdstate () & (~ios::failbit)); // XXX FIXME XXX -- is this the right thing to do? - // What about other streams? - if (name () == "stdin") + + if (interactive && name () == "stdin") { is.clear (); at @ -1351,8 +1352,8 @@ error ("fscanf: read error"); // XXX FIXME XXX -- is this the right thing to do? - // What about other streams? - if (name () == "stdin") + + if (interactive && name () == "stdin") { is.clear (); at @ -1534,8 +1535,8 @@ error ("fscanf: read error"); // XXX FIXME XXX -- is this the right thing to do? - // What about other streams? - if (name () == "stdin") + + if (interactive && name () == "stdin") { is.clear (); at @ -1586,12 +1587,8 @@ error ("fscanf: read error"); // XXX FIXME XXX -- is this the right thing to do? - // Maybe. We should probably also arrange to - // flush the pending input prior to printing a - // prompt. Or maybe just blow off scanf for stdin - // like the MathWorks did. What about other streams? - if (name () == "stdin") + if (interactive && name () == "stdin") { is.clear (); --------------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. To ensure that development continues, see www.che.wisc.edu/octave/giftform.html Instructions for unsubscribing: www.che.wisc.edu/octave/archive.html ---------------------------------------------------------------------