Mercurial > hg > octave-nkf
changeset 9701:531280b07625
implement fskipl
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Wed, 07 Oct 2009 11:08:54 +0200 |
parents | 95a30d00f779 |
children | 9ecd35a606e3 |
files | doc/ChangeLog doc/interpreter/io.txi src/ChangeLog src/file-io.cc src/oct-stream.cc src/oct-stream.h |
diffstat | 6 files changed, 162 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,7 @@ +2009-10-07 Jaroslav Hajek <highegg@gmail.com> + + * interpreter/io.txi: Add reference to fskipl. + 2009-09-30 John W. Eaton <jwe@octave.org> * interpreter/data.txi (Built-in Data Types):
--- a/doc/interpreter/io.txi +++ b/doc/interpreter/io.txi @@ -369,6 +369,8 @@ @DOCSTRING(fgets) +@DOCSTRING(fskipl) + @node Formatted Output @subsection Formatted Output
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2009-10-07 Jaroslav Hajek <highegg@gmail.com> + + * oct-stream.cc (octave_base_stream::skipl, + octave_stream::skipl (long, ...), octave_stream::skipl (const + octave_value&, ...)): New methods. + * oct-stream.h: Declare them. + * file-io.cc (Ffskipl): New DEFUN. + 2009-10-07 John W. Eaton <jwe@octave.org> * OPERATORS/op-str-str.cc (DEFUNOP (transpose, char_matrix_str)):
--- a/src/file-io.cc +++ b/src/file-io.cc @@ -396,6 +396,47 @@ return retval; } +DEFUN (fskipl, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} fskipl (@var{fid}, @var{count})\n\ +Skips a given number of lines, i.e. discards characters until an end-of-line\n\ +is met exactly @var{count}-times, or end-of-file occurs.\n\ +Returns the number of lines skipped (end-of-line sequences encountered).\n\ +If @var{count} is omitted, it defaults to 1. @var{count} may also be\n\ +@code{Inf}, in which case lines are skipped to the end of file.\n\ +This form is suitable for counting lines in a file.\n\ +@seealso{fgetl, fgets}\n\ +@end deftypefn") +{ + static std::string who = "fskipl"; + + octave_value retval; + + int nargin = args.length (); + + if (nargin == 1 || nargin == 2) + { + octave_stream os = octave_stream_list::lookup (args(0), who); + + if (! error_state) + { + octave_value count_arg = (nargin == 2) ? args(1) : octave_value (); + + bool err = false; + + long tmp = os.skipl (count_arg, err, who); + + if (! (error_state || err)) + retval = tmp; + } + } + else + print_usage (); + + return retval; +} + + static octave_stream do_stream_open (const std::string& name, const std::string& mode, const std::string& arch, int& fid)
--- a/src/oct-stream.cc +++ b/src/oct-stream.cc @@ -1070,6 +1070,65 @@ return do_gets (max_len, err, false, who); } +long +octave_base_stream::skipl (long num, bool& err, const std::string& who) +{ + long cnt = -1; + + if ((interactive || forced_interactive) && file_number () == 0) + { + ::error ("%s: unable to read from stdin while running interactively", + who.c_str ()); + + return count; + } + + err = false; + + std::istream *isp = input_stream (); + + if (isp) + { + std::istream& is = *isp; + + int c = 0, lastc = -1; + cnt = 0; + + while (is && (c = is.get ()) != EOF) + { + // Handle CRLF, CR, or LF as line ending. + + if (c == '\r' || (c == '\n' && lastc != '\r')) + { + if (++cnt == num) + break; + } + + lastc = c; + } + + // Maybe eat the following \n if \r was just met. + if (c == '\r' && is.peek () == '\n') + is.get (); + + if (is.bad ()) + { + err = true; + error (who, "read error"); + } + + if (err) + cnt = -1; + } + else + { + err = true; + invalid_operation (who, "reading"); + } + + return cnt; +} + #define OCTAVE_SCAN(is, fmt, arg) octave_scan (is, fmt, arg) template <class T> @@ -2918,6 +2977,50 @@ return retval; } +long +octave_stream::skipl (long count, bool& err, const std::string& who) +{ + long retval = -1; + + if (stream_ok ()) + retval = rep->skipl (count, err, who); + + return retval; +} + +long +octave_stream::skipl (const octave_value& tc_count, bool& err, const std::string& who) +{ + long retval = -1; + + err = false; + + int conv_err = 0; + + int count = 1; + + if (tc_count.is_defined ()) + { + if (tc_count.is_scalar_type () && xisinf (tc_count.scalar_value ())) + count = -1; + else + { + count = convert_to_valid_int (tc_count, conv_err); + + if (conv_err || count < 0) + { + err = true; + ::error ("%s: invalid number of lines specified", who.c_str ()); + } + } + } + + if (! error_state) + retval = skipl (count, err, who); + + return retval; +} + int octave_stream::seek (long offset, int origin) {
--- a/src/oct-stream.h +++ b/src/oct-stream.h @@ -438,6 +438,7 @@ std::string getl (octave_idx_type max_len, bool& err, const std::string& who /* = "getl" */); std::string gets (octave_idx_type max_len, bool& err, const std::string& who /* = "gets" */); + long skipl (long count, bool& err, const std::string& who /* = "skipl" */); octave_value do_scanf (scanf_format_list& fmt_list, octave_idx_type nr, octave_idx_type nc, bool one_elt_size_spec, octave_idx_type& count, @@ -501,6 +502,9 @@ std::string gets (const octave_value& max_len, bool& err, const std::string& who /* = "gets" */); + long skipl (long count, bool& err, const std::string& who /* = "skipl" */); + long skipl (const octave_value& count, bool& err, const std::string& who /* = "skipl" */); + int seek (long offset, int origin); int seek (const octave_value& offset, const octave_value& origin);