diff libinterp/corefcn/oct-stream.h @ 21502:7a19c5678f91

move textscan class to oct-stream.cc and textscan function to file-io.cc * file-io.cc (Ftextscan): Move here. * textxcan.cc: From here. * oct-stream.h, oct-stream.cc (delimited_stream, textscan_format_elt, textscan_format_list, textscan): Move here. * textscan.h, textscan.cc: From here. * textscan.h, textscan.cc: Delete. * libinterp/corefcn/module.mk: Update.
author John W. Eaton <jwe@octave.org>
date Sat, 19 Mar 2016 11:21:45 -0400
parents 4fc04d04dd9c
children 20bf0ec536e2
line wrap: on
line diff
--- a/libinterp/corefcn/oct-stream.h	Sat Mar 19 09:20:05 2016 -0400
+++ b/libinterp/corefcn/oct-stream.h	Sat Mar 19 11:21:45 2016 -0400
@@ -25,11 +25,9 @@
 
 #include "octave-config.h"
 
-#include <deque>
 #include <iosfwd>
 #include <list>
 #include <map>
-#include <sstream>
 #include <string>
 
 // These are only needed as arguments to private functions, so they
@@ -37,20 +35,177 @@
 
 class scanf_format_elt;
 class scanf_format_list;
+
 class printf_format_elt;
 class printf_format_list;
 
+class delimited_stream;
+class textscan_format_elt;
+class textscan_format_list;
+
 // These only appear as reference arguments or return values.
 
 template <typename T> class Array;
+class octave_value_list;
 class string_vector;
-class octave_value;
-class octave_value_list;
 
 #include "data-conv.h"
 #include "mach-info.h"
 #include "oct-refcount.h"
 
+#include "Cell.h"
+#include "ov.h"
+
+// Main class to implement textscan.  Read data and parse it
+// according to a format.
+//
+// The calling sequence is
+//
+//   textscan scanner ();
+//   scanner.scan (...);
+
+class
+OCTINTERP_API
+textscan
+{
+public:
+
+  textscan (void);
+
+  ~textscan (void) { }
+
+  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;
+
+  std::string buf;
+
+  // Three cases for delim_table and delim_list
+  // 1. delim_table empty, delim_list empty:  whitespace delimiters
+  // 2. delim_table = look-up table of delim chars, delim_list empty.
+  // 3. delim_table non-empty, delim_list = Cell array of delim strings
+
+  std::string whitespace_table;
+
+  // delim_table[i] == '\0' if i is not a delimiter.
+  std::string delim_table;
+
+  // String of delimiter characters.
+  std::string delims;
+
+  Cell comment_style;
+
+  // How far ahead to look to detect an open comment.
+  int comment_len;
+
+  // First character of open comment.
+  int comment_char;
+
+  octave_idx_type buffer_size;
+
+  std::string date_locale;
+
+  // 'inf' and 'nan' for formatted_double.
+  Cell inf_nan;
+
+  // Array of strings of delimiters.
+  Cell delim_list;
+
+  // Longest delimiter.
+  int delim_len;
+
+  octave_value empty_value;
+  std::string exp_chars;
+  int header_lines;
+  Cell treat_as_empty;
+
+  // Longest string to treat as "N/A".
+  int treat_as_empty_len;
+
+  std::string whitespace;
+
+  short eol1;
+  short eol2;
+  short return_on_error;
+
+  bool collect_output;
+  bool multiple_delims_as_one;
+  bool default_exp;
+  bool numeric_delim;
+
+  octave_idx_type lines;
+
+  octave_value do_scan (std::istream& isp, textscan_format_list& fmt_list,
+                        octave_idx_type ntimes);
+
+  void parse_options (const octave_value_list& args,
+                      textscan_format_list& fmt_list);
+
+  int read_format_once (delimited_stream& isp, textscan_format_list& fmt_list,
+                        std::list<octave_value>& retval,
+                        Array<octave_idx_type> row, int& done_after);
+
+  void scan_one (delimited_stream& is, const textscan_format_elt& fmt,
+                 octave_value& ov, Array<octave_idx_type> row);
+
+  // Methods to process a particular conversion specifier.
+  double read_double (delimited_stream& is,
+                      const textscan_format_elt& fmt) const;
+
+  void scan_complex (delimited_stream& is, const textscan_format_elt& fmt,
+                     Complex& val) const;
+
+  int scan_bracket (delimited_stream& is, const std::string& pattern,
+                    std::string& val) const;
+
+  int scan_caret (delimited_stream& is, const std::string& pattern,
+                  std::string& val) const;
+
+  void scan_string (delimited_stream& is, const textscan_format_elt& fmt,
+                    std::string& val) const;
+
+  void scan_cstring (delimited_stream& is, const textscan_format_elt& fmt,
+                     std::string& val) const;
+
+  void scan_qstring (delimited_stream& is, const textscan_format_elt& fmt,
+                     std::string& val);
+
+  // Helper methods.
+  std::string read_until (delimited_stream& is, const Cell& delimiters,
+                          const std::string& ends) const;
+
+  int lookahead (delimited_stream& is, const Cell& targets, int max_len,
+                 bool case_sensitive = true) const;
+
+  bool match_literal (delimited_stream& isp, const textscan_format_elt& elem);
+
+  int skip_whitespace (delimited_stream& is, bool EOLstop = false);
+
+  int skip_delim (delimited_stream& is);
+
+  bool is_delim (unsigned char ch) const
+  {
+    return ((delim_table.empty () && (isspace (ch) || ch == eol1 || ch == eol2))
+            || delim_table[ch] != '\0');
+  }
+
+  bool isspace (unsigned int ch) const { return whitespace_table[ch & 0xff]; }
+
+  // True if the only delimiter is whitespace.
+  bool whitespace_delim (void) const { return delim_table.empty (); }
+
+  // No copying!
+
+  textscan (const textscan&);
+
+  textscan& operator = (const textscan&);
+};
+
 // Provide an interface for Octave streams.
 
 class