# HG changeset patch # User John W. Eaton # Date 1458392004 14400 # Node ID 7a6589e2867aca3824ac31ed532f4053550260e2 # Parent 365c3e0add9838257235593e90e6cdd6d11beb7e more style fixes for textscan * textscan.h, textscan.cc (textscan::scan): New arg, COUNT. Compute number of characters consumed here instead of in Ftextscan. Use ovl to return results. Return Octave stream error message. (Ftextscan): Use octave_istrstream for reading character strings. diff -r 365c3e0add98 -r 7a6589e2867a libinterp/corefcn/textscan.cc --- a/libinterp/corefcn/textscan.cc Sat Mar 19 08:20:53 2016 -0400 +++ b/libinterp/corefcn/textscan.cc Sat Mar 19 08:53:24 2016 -0400 @@ -30,6 +30,7 @@ #include "Cell.h" #include "defun.h" #include "oct-stream.h" +#include "oct-strstrm.h" #include "ov.h" #include "ovl.h" #include "textscan.h" @@ -1240,6 +1241,15 @@ octave_value textscan::scan (std::istream& isp, const octave_value_list& args) { + octave_idx_type count = 0; + + return scan (isp, args, count); +} + +octave_value +textscan::scan (std::istream& isp, const octave_value_list& args, + octave_idx_type& count) +{ std::string format; int params = 0; @@ -1280,7 +1290,18 @@ parse_options (tmp_args, fmt_list); - return do_scan (isp, fmt_list, ntimes); + octave_value result = do_scan (isp, fmt_list, ntimes); + + // FIXME: this is probably not the best way to get count. The + // position could easily be larger than octave_idx_type when using + // 32-bit indexing. + + std::ios::iostate state = isp.rdstate (); + isp.clear (); + count = static_cast (isp.tellg ()); + isp.setstate (state); + + return result; } octave_value @@ -2742,7 +2763,7 @@ @deftypefnx {} {@var{C} =} textscan (@var{fid}, @var{format}, @var{param}, @var{value}, @dots{})\n\ @deftypefnx {} {@var{C} =} textscan (@var{fid}, @var{format}, @var{repeat}, @var{param}, @var{value}, @dots{})\n\ @deftypefnx {} {@var{C} =} textscan (@var{str}, @dots{})\n\ -@deftypefnx {} {[@var{C}, @var{position}] =} textscan (@dots{})\n\ +@deftypefnx {} {[@var{C}, @var{position}, @var{errmsg}] =} textscan (@dots{})\n\ Read data from a text file or string.\n\ \n\ The string @var{str} or file associated with @var{fid} is read from and\n\ @@ -3022,6 +3043,8 @@ @seealso{dlmread, fscanf, load, strread, textread}\n\ @end deftypefn") { + static std::string who = "textscan"; + octave_value_list retval; if (args.length () < 1) @@ -3029,33 +3052,41 @@ octave_value_list tmp_args = args.splice (0, 1); + octave_idx_type count = 0; + textscan tscanner; if (args(0).is_string ()) { - std::istringstream is (args(0).string_value ()); - - retval(0) = tscanner.scan (is, tmp_args); - - std::ios::iostate state = is.rdstate (); - is.clear (); - retval(1) = octave_value (static_cast (is.tellg ())); - is.setstate (state); + std::string data = args(0).string_value (); + + octave_stream os = octave_istrstream::create (data); + + if (! os.is_valid ()) + error ("%s: unable to create temporary input buffer", who.c_str ()); + + std::istream *isp = os.input_stream (); + + octave_value result = tscanner.scan (*isp, tmp_args, count); + + std::string errmsg = os.error (); + + return ovl (result, count, errmsg); } else { - octave_stream os = octave_stream_list::lookup (args(0), "textscan"); + octave_stream os = octave_stream_list::lookup (args(0), who); + std::istream *isp = os.input_stream (); + if (! isp) error ("internal error: textscan called with invalid istream"); - retval(0) = tscanner.scan (*isp, tmp_args); - - // FIXME -- warn if stream is not opened in binary mode? - std::ios::iostate state = os.input_stream ()->rdstate (); - os.input_stream ()->clear (); - retval(1) = os.tell (); - os.input_stream ()->setstate (state); + octave_value result = tscanner.scan (*isp, tmp_args, count); + + std::string errmsg = os.error (); + + return ovl (result, count, errmsg); } return retval; diff -r 365c3e0add98 -r 7a6589e2867a libinterp/corefcn/textscan.h --- a/libinterp/corefcn/textscan.h Sat Mar 19 08:20:53 2016 -0400 +++ b/libinterp/corefcn/textscan.h Sat Mar 19 08:53:24 2016 -0400 @@ -63,6 +63,9 @@ octave_value scan (std::istream& isp, const octave_value_list& args); + octave_value scan (std::istream& isp, const octave_value_list& args, + octave_idx_type& count); + private: friend class textscan_format_list;