26#if defined (HAVE_CONFIG_H)
89convert_to_valid_int (
const octave_value& tc,
int& conv_err)
112 if (! math::isnan (dval))
114 int ival = math::nint (dval);
129get_size (
double d,
const std::string& who)
134 ::error (
"%s: NaN invalid as size specification", who.c_str ());
141 ::error (
"%s: negative value invalid as size specification",
144 static constexpr double out_of_range_top
145 =
static_cast<double> (std::numeric_limits<octave_idx_type>::max ()) + 1.0;
146 if (
d >= out_of_range_top)
147 ::error (
"%s: dimension too large for Octave's index type",
150 retval = math::nint_big (
d);
159 bool& one_elt_size_spec,
const std::string& who)
164 one_elt_size_spec =
false;
173 one_elt_size_spec =
true;
177 dnc = (dnr == 0.0) ? 0.0 : 1.0;
179 else if (sz_len == 2)
183 if (math::isinf (dnr))
184 ::error (
"%s: infinite value invalid as size specification",
190 ::error (
"%s: invalid size specification (must be 2-D)", who.c_str ());
192 nr = get_size (dnr, who);
196 nc = get_size (dnc, who);
200 && nc > std::numeric_limits<octave_idx_type>::max () / nr)
201 ::error (
"%s: size too large for Octave's index type", who.c_str ());
206expand_char_class (
const std::string& s)
210 std::size_t
len = s.length ();
216 unsigned char c = s[i++];
218 if (c ==
'-' && i > 1 && i <
len
219 && (
static_cast<unsigned char> (s[i-2])
220 <=
static_cast<unsigned char> (s[i])))
225 for (c = s[i-2]+1; c < s[i]; c++)
233 if (c !=
'-' || i ==
len)
241class scanf_format_elt
245 enum special_conversion
247 whitespace_conversion = 1,
248 literal_conversion = 2,
252 scanf_format_elt (
const std::string& txt =
"",
int w = 0,
bool d =
false,
253 char typ =
'\0',
char mod =
'\0',
254 const std::string& ch_class =
"")
255 : text (txt), width (
w), discard (
d), type (typ),
256 modifier (
mod), char_class (ch_class)
259 scanf_format_elt (
const scanf_format_elt&) =
default;
261 scanf_format_elt& operator = (
const scanf_format_elt&) =
default;
263 ~scanf_format_elt () =
default;
282 std::string char_class;
285class scanf_format_list
289 scanf_format_list (
const std::string& fmt =
"");
291 OCTAVE_DISABLE_COPY_MOVE (scanf_format_list)
293 ~scanf_format_list ();
302 std::size_t length ()
const {
return m_fmt_elts.size (); }
304 const scanf_format_elt * first ()
310 const scanf_format_elt * current ()
const
312 return length () > 0 ? m_fmt_elts[m_curr_idx] :
nullptr;
315 const scanf_format_elt * next (
bool cycle =
true)
317 static scanf_format_elt dummy
318 (
"", 0,
false, scanf_format_elt::null,
'\0',
"");
322 if (m_curr_idx >= length ())
333 void printme ()
const;
335 bool ok ()
const {
return (m_nconv >= 0); }
337 operator bool ()
const {
return ok (); }
339 bool all_character_conversions ();
341 bool all_numeric_conversions ();
345 void add_elt_to_list (
int width,
bool discard,
char type,
char modifier,
346 const std::string& char_class =
"");
348 void process_conversion (
const std::string& s, std::size_t& i,
349 std::size_t n,
int& width,
bool& discard,
350 char& type,
char& modifier);
352 int finish_conversion (
const std::string& s, std::size_t& i, std::size_t n,
353 int width,
bool discard,
char& type,
363 std::size_t m_curr_idx;
366 std::deque<scanf_format_elt *> m_fmt_elts;
369 std::ostringstream m_buf;
373scanf_format_list::scanf_format_list (
const std::string& s)
374 : m_nconv (0), m_curr_idx (0), m_fmt_elts (), m_buf ()
376 std::size_t n = s.length ();
381 bool discard =
false;
382 char modifier =
'\0';
385 bool have_more =
true;
395 process_conversion (s, i, n, width, discard, type, modifier);
397 have_more = (m_buf.tellp () != 0);
399 else if (isspace (s[i]))
401 type = scanf_format_elt::whitespace_conversion;
408 while (++i < n && isspace (s[i]))
411 add_elt_to_list (width, discard, type, modifier);
417 type = scanf_format_elt::literal_conversion;
423 while (i < n && ! isspace (s[i]) && s[i] !=
'%')
426 add_elt_to_list (width, discard, type, modifier);
439 add_elt_to_list (width, discard, type, modifier);
445scanf_format_list::~scanf_format_list ()
447 std::size_t n = m_fmt_elts.size ();
449 for (std::size_t i = 0; i < n; i++)
451 scanf_format_elt *elt = m_fmt_elts[i];
457scanf_format_list::add_elt_to_list (
int width,
bool discard,
char type,
459 const std::string& char_class)
461 std::string text = m_buf.str ();
465 scanf_format_elt *elt
466 =
new scanf_format_elt (text, width, discard, type,
467 modifier, char_class);
469 m_fmt_elts.push_back (elt);
477scanf_format_list::process_conversion (
const std::string& s, std::size_t& i,
478 std::size_t n,
int& width,
479 bool& discard,
char& type,
489 bool have_width =
false;
505 case '0':
case '1':
case '2':
case '3':
case '4':
506 case '5':
case '6':
case '7':
case '8':
case '9':
512 width = 10 * width + c -
'0';
515 while (i < n && isdigit (s[i]))
518 width = 10 * width + c -
'0';
524 case 'h':
case 'l':
case 'L':
525 if (modifier !=
'\0')
532 case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
543 case 'e':
case 'f':
case 'g':
556 case 'c':
case 's':
case 'p':
case '%':
case '[':
557 if (modifier !=
'\0')
566 if (finish_conversion (s, i, n, width, discard,
567 type, modifier) == 0)
585scanf_format_list::finish_conversion (
const std::string& s, std::size_t& i,
586 std::size_t n,
int width,
bool discard,
587 char& type,
char modifier)
591 std::string char_class;
593 std::size_t beg_idx = std::string::npos;
594 std::size_t end_idx = std::string::npos;
626 else if (s[i] ==
']')
630 while (i < n && s[i] !=
']')
633 if (i < n && s[i] ==
']')
640 retval = m_nconv = -1;
650 if (beg_idx != std::string::npos && end_idx != std::string::npos)
651 char_class = expand_char_class (s.substr (beg_idx,
652 end_idx - beg_idx + 1));
654 add_elt_to_list (width, discard, type, modifier, char_class);
661scanf_format_list::printme ()
const
663 std::size_t n = m_fmt_elts.size ();
665 for (std::size_t i = 0; i < n; i++)
667 scanf_format_elt *elt = m_fmt_elts[i];
670 <<
"width: " << elt->width <<
"\n"
671 <<
"discard: " << elt->discard <<
"\n"
674 if (elt->type == scanf_format_elt::literal_conversion)
675 std::cerr <<
"literal text\n";
676 else if (elt->type == scanf_format_elt::whitespace_conversion)
677 std::cerr <<
"whitespace\n";
679 std::cerr << elt->type <<
"\n";
682 <<
"modifier: " << elt->modifier <<
"\n"
689scanf_format_list::all_character_conversions ()
691 std::size_t n = m_fmt_elts.size ();
695 for (std::size_t i = 0; i < n; i++)
697 scanf_format_elt *elt = m_fmt_elts[i];
701 case 'c':
case 's':
case '%':
case '[':
case '^':
702 case scanf_format_elt::literal_conversion:
703 case scanf_format_elt::whitespace_conversion:
719scanf_format_list::all_numeric_conversions ()
721 std::size_t n = m_fmt_elts.size ();
725 for (std::size_t i = 0; i < n; i++)
727 scanf_format_elt *elt = m_fmt_elts[i];
731 case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X':
732 case 'e':
case 'f':
case 'g':
case 'E':
case 'G':
747class printf_format_elt
751 printf_format_elt (
const std::string& txt =
"",
int n = 0,
int w = -1,
752 int p = -1,
const std::string&
f =
"",
753 char typ =
'\0',
char mod =
'\0')
754 : text (txt), args (n), fw (
w), prec (p), flags (
f),
755 type (typ), modifier (
mod)
758 printf_format_elt (
const printf_format_elt&) =
default;
760 printf_format_elt& operator = (
const printf_format_elt&) =
default;
762 ~printf_format_elt () =
default;
787class printf_format_list
791 printf_format_list (
const std::string& fmt =
"");
793 OCTAVE_DISABLE_COPY_MOVE (printf_format_list)
795 ~printf_format_list ();
799 const printf_format_elt * first ()
805 const printf_format_elt * current ()
const
807 return length () > 0 ? m_fmt_elts[m_curr_idx] :
nullptr;
810 std::size_t length ()
const {
return m_fmt_elts.size (); }
812 const printf_format_elt * next (
bool cycle =
true)
816 if (m_curr_idx >= length ())
827 bool last_elt_p () {
return (m_curr_idx + 1 == length ()); }
829 void printme ()
const;
831 bool ok ()
const {
return (m_nconv >= 0); }
833 operator bool ()
const {
return ok (); }
837 void add_elt_to_list (
int args,
const std::string& flags,
int fw,
838 int prec,
char type,
char modifier);
840 void process_conversion (
const std::string& s, std::size_t& i,
842 int& args, std::string& flags,
int& fw,
843 int& prec,
char& modifier,
char& type);
845 void finish_conversion (
const std::string& s, std::size_t& i,
int args,
846 const std::string& flags,
int fw,
int prec,
847 char modifier,
char& type);
856 std::size_t m_curr_idx;
859 std::deque<printf_format_elt *> m_fmt_elts;
862 std::ostringstream m_buf;
866printf_format_list::printf_format_list (
const std::string& s)
867 : m_nconv (0), m_curr_idx (0), m_fmt_elts (), m_buf ()
869 std::size_t n = s.length ();
877 char modifier =
'\0';
880 bool have_more =
true;
881 bool empty_buf =
true;
885 printf_format_elt *elt
886 =
new printf_format_elt (
"", args, fw, prec, flags, type, modifier);
888 m_fmt_elts.push_back (elt);
896 empty_buf = (m_buf.tellp () == 0);
904 process_conversion (s, i, n, args, flags, fw, prec,
913 have_more = (m_buf.tellp () != 0);
916 add_elt_to_list (args, flags, fw, prec, type, modifier);
941 add_elt_to_list (args, flags, fw, prec, type, modifier);
948printf_format_list::~printf_format_list ()
950 std::size_t n = m_fmt_elts.size ();
952 for (std::size_t i = 0; i < n; i++)
954 printf_format_elt *elt = m_fmt_elts[i];
960printf_format_list::add_elt_to_list (
int args,
const std::string& flags,
961 int fw,
int prec,
char type,
964 std::string text = m_buf.str ();
968 printf_format_elt *elt
969 =
new printf_format_elt (text, args, fw, prec, flags,
972 m_fmt_elts.push_back (elt);
980printf_format_list::process_conversion (
const std::string& s, std::size_t& i,
981 std::size_t n,
int& args,
982 std::string& flags,
int& fw,
983 int& prec,
char& modifier,
1001 case '-':
case '+':
case ' ':
case '0':
case '#':
1028 std::string tmp = s.substr (i);
1029 sscanf (tmp.c_str (),
"%d%n", &fw, &nn);
1032 while (i < n && isdigit (s[i]))
1037 if (i < n && s[i] ==
'.')
1061 std::string tmp = s.substr (i);
1062 sscanf (tmp.c_str (),
"%d%n", &prec, &nn);
1065 while (i < n && isdigit (s[i]))
1079 case 'h':
case 'l':
case 'L':
1089 finish_conversion (s, i, args, flags, fw, prec, modifier, type);
1095printf_format_list::finish_conversion (
const std::string& s, std::size_t& i,
1096 int args,
const std::string& flags,
1097 int fw,
int prec,
char modifier,
1102 case 'd':
case 'i':
case 'o':
case 'x':
case 'X':
1104 if (modifier ==
'L')
1111 case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
1112 if (modifier ==
'h' || modifier ==
'l')
1119 case 's':
case 'p':
case '%':
1120 if (modifier !=
'\0')
1133 if (type !=
'%' || args != 0)
1139 add_elt_to_list (args, flags, fw, prec, type, modifier);
1150printf_format_list::printme ()
const
1152 std::size_t n = m_fmt_elts.size ();
1154 for (std::size_t i = 0; i < n; i++)
1156 printf_format_elt *elt = m_fmt_elts[i];
1159 <<
"args: " << elt->args <<
"\n"
1160 <<
"flags: '" << elt->flags <<
"'\n"
1161 <<
"width: " << elt->fw <<
"\n"
1162 <<
"prec: " << elt->prec <<
"\n"
1163 <<
"type: '" << elt->type <<
"'\n"
1164 <<
"modifier: '" << elt->modifier <<
"'\n"
1173pown (
double x,
unsigned int n)
1177 for (
unsigned int d = n;
d;
d >>= 1)
1211class delimited_stream
1215 delimited_stream (std::istream& is,
const std::string& delimiters,
1218 delimited_stream (std::istream& is,
const delimited_stream& ds);
1220 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (delimited_stream)
1222 ~delimited_stream ();
1228 if (m_idx >= m_last)
1234 int refresh_buf (
bool initialize =
false);
1241 return eof () ? std::istream::traits_type::eof () : *m_idx++;
1243 return get_undelim ();
1254 {
return eof () ? std::istream::traits_type::eof () : *m_idx; }
1257 int peek_undelim ();
1263 void putback (
char = 0) {
if (! eof ()) --m_idx; }
1265 int getline (std::string& dest,
char delim);
1269 char * read (
char *buffer,
int size,
char *&new_start);
1273 char * tellg () {
return m_idx; }
1275 void seekg (
char *old_idx) { m_idx = old_idx; }
1279 return ((m_eob - m_buf) == m_overlap && m_i_stream.eof ())
1280 || (m_flags & std::ios_base::eofbit);
1283 operator const void *()
1284 {
return (! eof () && ! m_flags) ?
this : nullptr; }
1286 bool fail () {
return m_flags & std::ios_base::failbit; }
1288 std::ios_base::iostate rdstate () {
return m_flags; }
1290 void setstate (std::ios_base::iostate m) { m_flags = m_flags | m; }
1292 void clear (std::ios_base::iostate m
1293 = (std::ios_base::eofbit & ~std::ios_base::eofbit))
1295 m_flags = m_flags & m;
1301 void progress_benchmark () { m_progress_marker = m_idx; }
1303 bool no_progress () {
return m_progress_marker == m_idx; }
1308 std::ptrdiff_t remaining ()
1310 if (m_eob < m_buf + m_bufsize)
1311 return m_eob - m_idx;
1313 return std::numeric_limits<std::ptrdiff_t>::max ();
1322 std::istream& m_i_stream;
1338 std::ptrdiff_t m_overlap;
1347 const std::string m_delims;
1350 std::streampos m_buf_in_file;
1353 char *m_progress_marker;
1355 std::ios_base::iostate m_flags;
1362delimited_stream::delimited_stream (std::istream& is,
1363 const std::string& delimiters,
1364 int longest_lookahead,
1366 : m_bufsize (bsize), m_i_stream (is), m_longest (longest_lookahead),
1367 m_delims (delimiters),
1368 m_flags (std::ios::failbit & ~std::ios::failbit)
1370 m_buf =
new char[m_bufsize];
1371 m_eob = m_buf + m_bufsize;
1374 m_progress_marker = m_idx;
1379delimited_stream::delimited_stream (std::istream& is,
1380 const delimited_stream& ds)
1381 : delimited_stream (is, ds.m_delims, ds.m_longest, ds.m_bufsize)
1384delimited_stream::~delimited_stream ()
1389 m_i_stream.clear ();
1390 m_i_stream.seekg (m_buf_in_file);
1391 m_i_stream.read (m_buf, m_idx - m_buf - m_overlap);
1401delimited_stream::get_undelim ()
1406 setstate (std::ios_base::failbit);
1407 return std::istream::traits_type::eof ();
1418 setstate (std::ios_base::eofbit);
1419 retval = std::istream::traits_type::eof ();
1425 if (m_idx >= m_last)
1426 m_delimited =
false;
1435delimited_stream::peek_undelim ()
1437 int retval = get_undelim ();
1449delimited_stream::refresh_buf (
bool initialize)
1452 return std::istream::traits_type::eof ();
1459 std::size_t old_remaining = m_eob - m_idx;
1460 std::size_t old_overlap = 0;
1462 if (initialize || (m_idx - m_buf <= 0))
1466 old_overlap = m_overlap;
1473 m_overlap = std::min (m_overlap, m_idx - m_buf - 1);
1478 if (old_remaining + m_overlap > 0)
1480 m_buf_in_file += (m_idx - old_overlap - m_buf);
1481 std::memmove (m_buf, m_idx - m_overlap, m_overlap + old_remaining);
1484 m_buf_in_file = m_i_stream.tellg ();
1487 m_progress_marker -= m_idx - m_overlap - m_buf;
1488 m_idx = m_buf + m_overlap;
1491 if (! m_i_stream.eof ())
1493 m_i_stream.read (m_buf + m_overlap + old_remaining,
1494 m_bufsize - m_overlap - old_remaining);
1495 gcount = m_i_stream.gcount ();
1500 m_eob = m_buf + m_overlap + old_remaining + gcount;
1504 m_delimited =
false;
1506 if (m_eob != m_buf + m_overlap)
1511 retval = std::istream::traits_type::eof ();
1517 for (m_last = m_eob - m_longest; m_last - m_buf - m_overlap >= 0;
1520 if (m_delims.find (*m_last) != std::string::npos)
1524 if (m_last < m_buf + m_overlap)
1525 m_delimited =
false;
1531 if (retval == std::istream::traits_type::eof ())
1544delimited_stream::read (
char *buffer,
int size,
char *&prior_tell)
1548 if (m_eob - m_idx >= size)
1553 m_delimited =
false;
1562 if (m_eob - prior_tell + size < m_bufsize)
1576 if (m_eob - m_idx > size)
1581 m_delimited =
false;
1585 if (size <= m_bufsize)
1588 memset (m_eob, 0, size + (m_idx - m_buf));
1596 for (i = 0; i < size && ! eof (); i++)
1597 *buffer++ = get_undelim ();
1599 memset (buffer, 0, size - i);
1611delimited_stream::getline (std::string& out,
char delim)
1613 int len = out.length ();
1616 while ((ch = get_undelim ()) != delim
1617 && ch != std::istream::traits_type::eof ())
1634class textscan_format_elt
1638 enum special_conversion
1640 whitespace_conversion = 1,
1641 literal_conversion = 2
1644 textscan_format_elt () =
delete;
1646 textscan_format_elt (
const std::string& txt,
int w = 0,
int p = -1,
1647 int bw = 0,
bool dis =
false,
char typ =
'\0',
1648 const std::string& ch_class = std::string ())
1649 : text (txt), width (
w), prec (p), bitwidth (bw),
1650 char_class (ch_class), type (typ), discard (dis),
1651 numeric (typ ==
'd' || typ ==
'u' || type ==
'f' || type ==
'n')
1654 OCTAVE_DEFAULT_COPY_MOVE_DELETE (textscan_format_elt)
1671 std::string char_class;
1688class textscan_format_list
1692 textscan_format_list (
const std::string& fmt = std::string (),
1693 const std::string& who =
"textscan");
1695 OCTAVE_DISABLE_COPY_MOVE (textscan_format_list)
1697 ~textscan_format_list ();
1706 std::size_t
numel ()
const {
return m_fmt_elts.size (); }
1708 const textscan_format_elt * first ()
1714 const textscan_format_elt * current ()
const
1716 return numel () > 0 ? m_fmt_elts[m_curr_idx] :
nullptr;
1719 const textscan_format_elt * next (
bool cycle =
true)
1723 if (m_curr_idx >= numel ())
1734 void printme ()
const;
1736 bool ok ()
const {
return (m_nconv >= 0); }
1738 operator const void *()
const {
return ok () ? this :
nullptr; }
1744 bool set_from_first;
1749 int read_first_row (delimited_stream& is, textscan& ts);
1751 std::list<octave_value> out_buf ()
const
1752 {
return (m_output_container); }
1756 void add_elt_to_list (
unsigned int width,
int prec,
int bitwidth,
1759 const std::string& char_class = std::string ());
1761 void process_conversion (
const std::string& s, std::size_t& i,
1764 std::string parse_char_class (
const std::string& pattern)
const;
1766 int finish_conversion (
const std::string& s, std::size_t& i, std::size_t n,
1767 unsigned int width,
int prec,
int bitwidth,
1769 bool discard,
char& type);
1778 std::size_t m_curr_idx;
1781 std::deque<textscan_format_elt *> m_fmt_elts;
1784 std::list<octave_value> m_output_container;
1787 std::ostringstream m_buf;
1799class OCTINTERP_API textscan
1803 textscan (
const std::string& who_arg =
"textscan",
1804 const std::string& encoding =
"utf-8");
1806 OCTAVE_DISABLE_COPY_MOVE (textscan)
1808 ~textscan () =
default;
1810 octave_value scan (std::istream& isp,
const std::string& fmt,
1817 friend class textscan_format_list;
1819 octave_value do_scan (std::istream& isp, textscan_format_list& fmt_list,
1823 textscan_format_list& fmt_list);
1825 int read_format_once (delimited_stream& isp, textscan_format_list& fmt_list,
1826 std::list<octave_value>& retval,
1829 void scan_one (delimited_stream& is,
const textscan_format_elt& fmt,
1833 double read_double (delimited_stream& is,
1834 const textscan_format_elt& fmt)
const;
1836 void scan_complex (delimited_stream& is,
const textscan_format_elt& fmt,
1839 int scan_bracket (delimited_stream& is,
const std::string& pattern,
1840 std::string& val)
const;
1842 int scan_caret (delimited_stream& is,
const std::string& pattern,
1843 std::string& val)
const;
1845 void scan_string (delimited_stream& is,
const textscan_format_elt& fmt,
1846 std::string& val)
const;
1848 void scan_cstring (delimited_stream& is,
const textscan_format_elt& fmt,
1849 std::string& val)
const;
1851 void scan_qstring (delimited_stream& is,
const textscan_format_elt& fmt,
1855 std::string read_until (delimited_stream& is,
const Cell& delimiters,
1856 const std::string& ends)
const;
1858 int lookahead (delimited_stream& is,
const Cell& targets,
int max_len,
1859 bool case_sensitive =
true)
const;
1861 bool match_literal (delimited_stream& isp,
const textscan_format_elt& elem);
1863 int skip_whitespace (delimited_stream& is,
bool EOLstop =
true);
1865 int skip_delim (delimited_stream& is);
1867 bool is_delim (
unsigned char ch)
const
1869 return ((m_delim_table.empty ()
1870 && (isspace (ch) || ch == m_eol1 || ch == m_eol2))
1871 || m_delim_table[ch] !=
'\0');
1874 bool isspace (
unsigned int ch)
const
1875 {
return m_whitespace_table[ch & 0xff]; }
1878 bool whitespace_delim ()
const {
return m_delim_table.empty (); }
1885 std::string m_encoding;
1894 std::string m_whitespace_table;
1897 std::string m_delim_table;
1900 std::string m_delims;
1902 Cell m_comment_style;
1912 std::string m_date_locale;
1924 std::string m_exp_chars;
1926 Cell m_treat_as_empty;
1929 int m_treat_as_empty_len;
1931 std::string m_whitespace;
1935 short m_return_on_error;
1937 bool m_collect_output;
1938 bool m_multiple_delims_as_one;
1944textscan_format_list::textscan_format_list (
const std::string& s,
1945 const std::string& who_arg)
1946 : who (who_arg), set_from_first (false), has_string (false),
1947 m_nconv (0), m_curr_idx (0), m_fmt_elts (), m_buf ()
1949 std::size_t n = s.length ();
1953 unsigned int width = -1;
1956 bool discard =
false;
1959 bool have_more =
true;
1973 set_from_first =
true;
1978 set_from_first =
false;
1984 if (s[i] ==
'%' && (i+1 == n || s[i+1] !=
'%'))
1988 process_conversion (s, i, n);
1996 have_more = (m_buf.tellp () != 0);
1998 else if (isspace (s[i]))
2000 while (++i < n && isspace (s[i]))
2007 type = textscan_format_elt::literal_conversion;
2014 while (i < n && ! isspace (s[i])
2015 && (s[i] !=
'%' || (i+1 < n && s[i+1] ==
'%')))
2023 add_elt_to_list (width, prec, bitwidth,
octave_value (),
2038 add_elt_to_list (width, prec, bitwidth,
octave_value (), discard, type);
2044textscan_format_list::~textscan_format_list ()
2046 std::size_t n =
numel ();
2048 for (std::size_t i = 0; i < n; i++)
2050 textscan_format_elt *elt = m_fmt_elts[i];
2056textscan_format_list::add_elt_to_list (
unsigned int width,
int prec,
2058 bool discard,
char type,
2059 const std::string& char_class)
2061 std::string text = m_buf.str ();
2063 if (! text.empty ())
2065 textscan_format_elt *elt
2066 =
new textscan_format_elt (text, width, prec, bitwidth, discard,
2070 m_output_container.push_back (val_type);
2072 m_fmt_elts.push_back (elt);
2080textscan_format_list::process_conversion (
const std::string& s,
2081 std::size_t& i, std::size_t n)
2086 bool discard =
false;
2092 bool have_width =
false;
2108 case '0':
case '1':
case '2':
case '3':
case '4':
2109 case '5':
case '6':
case '7':
case '8':
case '9':
2115 width = width * 10 + c -
'0';
2118 while (i < n && isdigit (s[i]))
2121 width = width * 10 + c -
'0';
2125 if (i < n && s[i] ==
'.')
2129 while (i < n && isdigit (s[i]))
2132 prec = prec * 10 + c -
'0';
2142 m_buf << (type = s[i++]);
2154 else if (s[i] ==
'1' && i+1 < n && s[i+1] ==
'6')
2164 else if (s[i] ==
'3' && i+1 < n && s[i+1] ==
'2')
2170 else if (s[i] ==
'6' && i+1 < n && s[i+1] ==
'4')
2198 m_buf << (type = s[i++]);
2202 if (s[i] ==
'3' && i+1 < n && s[i+1] ==
'2')
2209 else if (s[i] ==
'6' && i+1 < n && s[i+1] ==
'4')
2223 m_buf << (type = s[i++]);
2228 case 's':
case 'q':
case '[':
case 'c':
2231 m_buf << (type = s[i++]);
2242 width =
static_cast<unsigned int> (-1);
2245 if (finish_conversion (s, i, n, width, prec, bitwidth, val_type,
2246 discard, type) == 0)
2252 error (
"%s: '%%%c' is not a valid format specifier",
2253 who.c_str (), s[i]);
2276textscan_format_list::parse_char_class (
const std::string& pattern)
const
2278 int len = pattern.length ();
2282 std::string retval (256,
'\0');
2283 std::string mask (256,
'\0');
2285 int in = 0, out = 0;
2286 unsigned char ch, prev = 0;
2295 mask[pattern[in]] =
'\1';
2296 retval[out++] = pattern[in++];
2298 bool prev_was_range =
false;
2299 bool prev_prev_was_range =
false;
2300 for (; in <
len; in++)
2302 bool was_range =
false;
2307 if (prev ==
'-' && in > 1 && isalnum (ch) && ! prev_prev_was_range)
2309 unsigned char start_of_range = pattern[in-2];
2310 if (start_of_range < ch
2311 && ((isupper (ch) && isupper (start_of_range))
2312 || (islower (ch) && islower (start_of_range))
2313 || (isdigit (ch) && isdigit (start_of_range))
2319 for (
int i = start_of_range; i <= ch; i++)
2321 if (mask[i] ==
'\0')
2331 if (mask[ch]++ == 0)
2335 "%s: [...] contains two '%c's",
2338 if (prev ==
'-' && mask[
'-'] >= 2)
2340 (
"Octave:textscan-pattern",
2341 "%s: [...] contains two '-'s outside range expressions",
2345 prev_prev_was_range = prev_was_range;
2346 prev_was_range = was_range;
2352 for (
int i = 0; i < 256; i++)
2357 retval.resize (out);
2363textscan_format_list::finish_conversion (
const std::string& s, std::size_t& i,
2364 std::size_t n,
unsigned int width,
2365 int prec,
int bitwidth,
2371 std::string char_class;
2373 std::size_t beg_idx = std::string::npos;
2374 std::size_t end_idx = std::string::npos;
2398 else if (s[i] ==
']')
2402 while (i < n && s[i] !=
']')
2405 if (i < n && s[i] ==
']')
2412 retval = m_nconv = -1;
2418 if (beg_idx != std::string::npos && end_idx != std::string::npos)
2419 char_class = parse_char_class (s.substr (beg_idx,
2420 end_idx - beg_idx + 1));
2422 add_elt_to_list (width, prec, bitwidth, val_type, discard, type,
2430textscan_format_list::printme ()
const
2432 std::size_t n =
numel ();
2434 for (std::size_t i = 0; i < n; i++)
2436 textscan_format_elt *elt = m_fmt_elts[i];
2439 <<
"width: " << elt->width <<
"\n"
2440 <<
"digits " << elt->prec <<
"\n"
2441 <<
"bitwidth: " << elt->bitwidth <<
"\n"
2442 <<
"discard: " << elt->discard <<
"\n"
2445 if (elt->type == textscan_format_elt::literal_conversion)
2446 std::cerr <<
"literal text\n";
2447 else if (elt->type == textscan_format_elt::whitespace_conversion)
2448 std::cerr <<
"whitespace\n";
2450 std::cerr << elt->type <<
"\n";
2462textscan_format_list::read_first_row (delimited_stream& is, textscan& ts)
2465 std::string first_line (20,
' ');
2467 is.getline (first_line,
static_cast<char> (ts.m_eol2));
2469 if (! first_line.empty () && first_line.back () == ts.m_eol1)
2470 first_line.pop_back ();
2472 std::istringstream strstr (first_line);
2473 delimited_stream ds (strstr, is);
2479 int max_empty = 1000;
2485 bool already_skipped_delim =
false;
2486 ts.skip_whitespace (ds,
false);
2487 ds.progress_benchmark ();
2488 ts.scan_complex (ds, *m_fmt_elts[0], val);
2491 ds.clear (ds.rdstate () & ~std::ios::failbit);
2499 if (ds.no_progress ())
2504 already_skipped_delim =
true;
2506 val = ts.m_empty_value.scalar_value ();
2512 if (val.imag () == 0)
2517 m_output_container.push_back (val_type);
2519 if (! already_skipped_delim)
2522 if (ds.no_progress ())
2528 m_output_container.pop_front ();
2532 m_fmt_elts.push_back (
new textscan_format_elt (*m_fmt_elts[0]));
2537textscan::textscan (
const std::string& who_arg,
const std::string& encoding)
2538 : m_who (who_arg), m_encoding (encoding), m_buf (), m_whitespace_table (),
2539 m_delim_table (), m_delims (), m_comment_style (), m_comment_len (0),
2540 m_comment_char (-2), m_buffer_size (0), m_date_locale (),
2541 m_inf_nan (init_inf_nan ()),
2542 m_empty_value (numeric_limits<
double>::
NaN ()),
2543 m_exp_chars (
"edED"), m_header_lines (0), m_treat_as_empty (),
2544 m_treat_as_empty_len (0), m_whitespace (
" \b\t"), m_eol1 (
'\r'),
2545 m_eol2 (
'\n'), m_return_on_error (1), m_collect_output (false),
2546 m_multiple_delims_as_one (false), m_default_exp (true), m_lines (0)
2550textscan::scan (std::istream& isp,
const std::string& fmt,
2554 textscan_format_list fmt_list (fmt);
2556 parse_options (options, fmt_list);
2564 std::ios::iostate state = isp.rdstate ();
2567 isp.setstate (state);
2573textscan::do_scan (std::istream& isp, textscan_format_list& fmt_list,
2578 if (fmt_list.num_conversions () == -1)
2579 error (
"%s: invalid format specified", m_who.c_str ());
2581 if (fmt_list.num_conversions () == 0)
2582 error (
"%s: no valid format conversion specifiers", m_who.c_str ());
2586 for (
int i = 0; i < m_header_lines && isp; i++)
2587 getline (isp, dummy,
static_cast<char> (m_eol2));
2592 int max_lookahead = std::max ({m_comment_len, m_treat_as_empty_len,
2598 buf_size = m_buffer_size;
2599 else if (ntimes > 0)
2602 buf_size = std::min (buf_size, std::max (ntimes, 80 * ntimes));
2603 buf_size = std::max (buf_size, ntimes);
2606 delimited_stream is (isp,
2607 (m_delims.empty () ? m_whitespace +
"\r\n"
2609 max_lookahead, buf_size);
2620 if (m_multiple_delims_as_one)
2626 if (fmt_list.set_from_first)
2628 err = fmt_list.read_first_row (is, *
this);
2631 done_after = fmt_list.numel () + 1;
2636 done_after = fmt_list.out_buf ().size () + 1;
2638 std::list<octave_value> out = fmt_list.out_buf ();
2646 std::vector<bool> merge_with_prev (fmt_list.numel ());
2648 if (m_collect_output)
2651 for (
const auto& col : out)
2653 if (col.type_id () == prev_type
2654 || (fmt_list.set_from_first && prev_type != -1))
2655 merge_with_prev[conv++] =
true;
2657 merge_with_prev[conv++] =
false;
2659 prev_type = col.type_id ();
2665 if (fmt_list.num_conversions () == 0)
2666 error (
"%s: No conversions specified", m_who.c_str ());
2672 row < ntimes || ntimes == -1;
2675 if (row == 0 || row >= size)
2678 for (
auto& col : out)
2683 err = read_format_once (is, fmt_list, out, row_idx, done_after);
2685 if ((err & ~1) > 0 || ! is || (m_lines >= ntimes && ntimes > -1))
2690 if ((err & 4) && ! m_return_on_error)
2691 error (
"%s: Read error in field %d of row %" OCTAVE_IDX_TYPE_FORMAT,
2692 m_who.c_str (), done_after + 1, row + 1);
2695 bool uneven_columns =
false;
2697 uneven_columns =
true;
2698 else if (isp.eof ())
2701 isp.seekg (-1, std::ios_base::end);
2702 int last_char = isp.get ();
2703 isp.setstate (isp.eofbit);
2704 uneven_columns = (last_char != m_eol1 && last_char != m_eol2);
2713 done_after = out.size () + 1;
2715 int valid_rows = (row == ntimes
2717 : ((err & 1) && (err & 8)) ? row : row+1);
2722 if (! m_collect_output)
2725 for (
auto& col : out)
2728 if (i == done_after && uneven_columns)
2729 dv =
dim_vector (std::max (valid_rows - 1, 0), 1);
2745 for (
auto& col : out)
2747 if (! merge_with_prev[conv++])
2749 if (prev_type != -1)
2756 prev_type = col.type_id ();
2760 ra_idx(1) = group_size++;
2775textscan::read_double (delimited_stream& is,
2776 const textscan_format_elt& fmt)
const
2779 unsigned int width_left = fmt.width;
2783 int ch = is.peek_undelim ();
2788 ch = is.peek_undelim ();
2796 ch = is.peek_undelim ();
2804 if (ch >=
'0' && ch <=
'9')
2806 while (width_left-- && is && (ch = is.get ()) >=
'0' && ch <=
'9')
2807 retval = retval * 10 + (ch -
'0');
2812 if (ch ==
'.' && width_left)
2814 double multiplier = 1;
2815 int precision = fmt.prec;
2820 if (precision == -1)
2826 for (i = 0; i < precision; i++)
2828 if (width_left-- && is && (ch = is.get ()) >=
'0' && ch <=
'9')
2829 retval += (ch -
'0') * (multiplier *= 0.1);
2838 if ((i == precision || ! width_left) && (ch = is.get ()) >=
'5'
2840 retval += multiplier;
2852 while (width_left-- && is && (ch = is.get ()) >=
'0' && ch <=
'9')
2859 bool used_exp =
false;
2860 if (valid && width_left > 1 && m_exp_chars.find (ch) != std::string::npos)
2862 int ch1 = is.peek_undelim ();
2863 if (ch1 ==
'-' || ch1 ==
'+' || (ch1 >=
'0' && ch1 <=
'9'))
2874 else if (ch1 ==
'-')
2881 while (width_left-- && is && (ch = is.get_undelim ()) >=
'0' && ch <=
'9')
2883 exp = exp*10 + ch -
'0';
2887 if (ch != std::istream::traits_type::eof () && width_left)
2890 double multiplier = pown (10, exp);
2892 retval *= multiplier;
2894 retval /= multiplier;
2900 if (! used_exp && ch != std::istream::traits_type::eof () && width_left)
2904 if (! valid && width_left >= 3 && is.remaining () >= 3)
2906 int i = lookahead (is, m_inf_nan, 3,
false);
2909 retval = numeric_limits<double>::Inf ();
2914 retval = numeric_limits<double>::NaN ();
2920 is.setstate (std::ios::failbit);
2922 is.setstate (is.rdstate () & ~std::ios::failbit);
2924 return retval * sign;
2932textscan::scan_complex (delimited_stream& is,
const textscan_format_elt& fmt,
2937 bool as_empty =
false;
2940 int ch = is.peek_undelim ();
2941 if (ch ==
'+' || ch ==
'-')
2944 int ch2 = is.peek_undelim ();
2945 if (ch2 ==
'i' || ch2 ==
'j')
2950 if (is.peek_undelim () ==
'n')
2952 char *pos = is.tellg ();
2953 std::ios::iostate state = is.rdstate ();
2956 ch2 = is.get_undelim ();
2960 re = (ch ==
'+' ? numeric_limits<double>::Inf ()
2973 im = (ch ==
'+') ? value : -value;
2981 char *pos = is.tellg ();
2982 std::ios::iostate state = is.rdstate ();
2985 re = read_double (is, fmt);
2988 if (m_treat_as_empty.numel ()
2989 && (is.fail () || math::is_NaN_or_NA (
Complex (re))
2990 || re == numeric_limits<double>::Inf ()))
2993 for (
int i = 0; i < m_treat_as_empty.numel (); i++)
2995 if (ch == m_treat_as_empty (i).string_value ()[0])
3011 std::string look_buf (m_treat_as_empty_len,
'\0');
3012 char *look = is.read (&look_buf[0], look_buf.size (), pos);
3018 for (
int i = 0; i < m_treat_as_empty.numel (); i++)
3020 std::string s = m_treat_as_empty (i).string_value ();
3021 if (!
strncmp (s.c_str (), look, s.size ()))
3025 is.read (&look_buf[0], s.size (), pos);
3032 if (! is.eof () && ! as_empty)
3034 state = is.rdstate ();
3036 ch = is.peek_undelim ();
3038 if (ch ==
'i' || ch ==
'j')
3044 else if (ch ==
'+' || ch ==
'-')
3048 state = is.rdstate ();
3053 im = read_double (is, fmt);
3057 if (is.peek_undelim () ==
'i' || is.peek_undelim () ==
'j')
3071 val = m_empty_value.scalar_value ();
3079textscan::scan_caret (delimited_stream& is,
const std::string& pattern,
3080 std::string& val)
const
3082 int c1 = std::istream::traits_type::eof ();
3083 std::ostringstream obuf;
3085 while (is && ((c1 = (is && ! is.eof ())
3087 : std::
istream::traits_type::eof ())
3088 != std::
istream::traits_type::eof ())
3089 && pattern.find (c1) == std::string::npos)
3090 obuf << static_cast<char> (c1);
3094 if (c1 != std::istream::traits_type::eof ())
3104textscan::read_until (delimited_stream& is,
const Cell& delimiters,
3105 const std::string& ends)
const
3107 std::string retval (
"");
3113 scan_caret (is, ends.c_str (), next);
3114 retval = retval + next;
3116 int last = (! is.eof ()
3117 ? is.get_undelim () : std::istream::traits_type::eof ());
3119 if (last != std::istream::traits_type::eof ())
3121 if (last == m_eol1 || last == m_eol2)
3124 retval = retval +
static_cast<char> (last);
3125 for (
int i = 0; i < delimiters.
numel (); i++)
3127 std::string delim = delimiters(i).string_value ();
3128 std::size_t start = (retval.length () > delim.length ()
3129 ? retval.length () - delim.length ()
3131 std::string may_match = retval.substr (start);
3132 if (may_match == delim)
3135 retval = retval.substr (0, start);
3143 while (! done && is && ! is.eof ());
3153textscan::scan_string (delimited_stream& is,
const textscan_format_elt& fmt,
3154 std::string& val)
const
3156 if (m_delim_list.isempty ())
3159 unsigned int width = fmt.width;
3161 for (i = 0; i < width; i++)
3164 if (i >= val.length ())
3165 val.append (std::max (val.length (),
3166 static_cast<std::size_t
> (16)),
'\0');
3168 int ch = is.get_undelim ();
3169 if (is_delim (ch) || ch == std::istream::traits_type::eof ())
3177 val = val.substr (0, i);
3181 std::string ends (m_delim_list.numel () + 2,
'\0');
3183 for (i = 0; i < m_delim_list.numel (); i++)
3185 std::string tmp = m_delim_list(i).string_value ();
3186 ends[i] = tmp.back ();
3190 val = textscan::read_until (is, m_delim_list, ends);
3194 if (m_encoding.compare (
"utf-8"))
3195 val = string::u8_from_encoding (
"textscan", val, m_encoding);
3201textscan::scan_bracket (delimited_stream& is,
const std::string& pattern,
3202 std::string& val)
const
3204 int c1 = std::istream::traits_type::eof ();
3205 std::ostringstream obuf;
3207 while (is && pattern.find (c1 = is.get_undelim ()) != std::string::npos)
3208 obuf << static_cast<char> (c1);
3211 if (c1 != std::istream::traits_type::eof ())
3221textscan::scan_qstring (delimited_stream& is,
const textscan_format_elt& fmt,
3224 skip_whitespace (is);
3226 if (is.peek_undelim () !=
'"')
3227 scan_string (is, fmt, val);
3231 scan_caret (is, R
"(")", val);
3234 while (is && is.peek_undelim () ==
'"')
3238 scan_caret (is, R
"(")", val1);
3239 val = val + '"' + val1;
3245 if (m_encoding.compare (
"utf-8"))
3246 val = string::u8_from_encoding (
"textscan", val, m_encoding);
3253textscan::scan_cstring (delimited_stream& is,
const textscan_format_elt& fmt,
3254 std::string& val)
const
3256 val.resize (fmt.width);
3258 for (
unsigned int i = 0; is && i < fmt.width; i++)
3260 int ch = is.get_undelim ();
3261 if (ch != std::istream::traits_type::eof ())
3271 if (m_encoding.compare (
"utf-8"))
3272 val = string::u8_from_encoding (
"textscan", val, m_encoding);
3278textscan::scan_one (delimited_stream& is,
const textscan_format_elt& fmt,
3281 skip_whitespace (is);
3288 if (fmt.type ==
'f' || fmt.type ==
'n')
3291 skip_whitespace (is);
3292 scan_complex (is, fmt, v);
3294 if (! fmt.discard && ! is.fail ())
3296 if (fmt.bitwidth == 64)
3298 if (ov.
isreal () && v.imag () == 0)
3310 if (ov.
isreal () && v.imag () == 0)
3329 skip_whitespace (is);
3330 v = read_double (is, fmt);
3331 if (! fmt.discard && ! is.fail ())
3332 switch (fmt.bitwidth)
3373 if (fmt.type ==
'd')
3386 if (fmt.type ==
'd')
3400 if (is.fail () & ! fmt.discard)
3401 ov =
cat_op (ov, m_empty_value, row);
3405 std::string vv (
" ");
3409 scan_string (is, fmt, vv);
3413 scan_qstring (is, fmt, vv);
3417 scan_cstring (is, fmt, vv);
3421 scan_bracket (is, fmt.char_class.c_str (), vv);
3425 scan_caret (is, fmt.char_class.c_str (), vv);
3435 is.clear (is.rdstate () & ~std::ios_base::failbit);
3445textscan::read_format_once (delimited_stream& is,
3446 textscan_format_list& fmt_list,
3447 std::list<octave_value>& retval,
3450 const textscan_format_elt *elem = fmt_list.first ();
3451 auto out = retval.begin ();
3452 bool no_conversions =
true;
3454 bool conversion_failed =
false;
3455 bool nothing_worked =
true;
3459 for (std::size_t i = 0; i < fmt_list.numel (); i++)
3461 bool this_conversion_failed =
false;
3470 warning (
"%s: conversion %c not yet implemented",
3471 m_who.c_str (), elem->type);
3483 scan_one (is, *elem, *out, row);
3486 case textscan_format_elt::literal_conversion :
3487 match_literal (is, *elem);
3491 error (
"Unknown format element '%c'", elem->type);
3496 if (! elem->discard)
3497 no_conversions =
false;
3501 is.clear (is.rdstate () & ~std::ios::failbit);
3505 if (m_delim_list.isempty ())
3507 if (! is_delim (is.peek_undelim ()))
3508 this_conversion_failed =
true;
3512 char *pos = is.tellg ();
3513 if (-1 == lookahead (is, m_delim_list, m_delim_len))
3514 this_conversion_failed =
true;
3521 if (! elem->discard)
3524 elem = fmt_list.next ();
3525 char *pos = is.tellg ();
3530 if (elem->type != textscan_format_elt::literal_conversion)
3532 else if (! is_delim (elem->text[0]))
3544 if (this_conversion_failed)
3546 if (is.tellg () == pos && ! conversion_failed)
3550 conversion_failed =
true;
3553 this_conversion_failed =
false;
3555 else if (! done && ! conversion_failed)
3556 nothing_worked =
false;
3560 is.setstate (std::ios::eofbit);
3562 return no_conversions
3563 + (is.eof () ? 2 : 0)
3564 + (conversion_failed ? 4 : 0)
3565 + (nothing_worked ? 8 : 0);
3571 textscan_format_list& fmt_list)
3573 int last = args.
length ();
3577 error (
"%s: %d parameters given, but only %d values",
3578 m_who.c_str (), n-n/2, n/2);
3581 bool have_delims =
false;
3582 for (
int i = 0; i < last; i += 2)
3584 std::string param = args(i).xstring_value (
"%s: Invalid parameter type <%s> for parameter %d",
3586 args(i).type_name ().c_str (),
3588 std::transform (param.begin (), param.end (), param.begin (), ::tolower);
3590 if (param ==
"delimiter")
3592 bool invalid =
true;
3593 if (args(i+1).is_string ())
3597 m_delims = args(i+1).string_value ();
3598 if (args(i+1).is_sq_string ())
3601 else if (args(i+1).iscell ())
3605 m_delim_table =
" ";
3608 for (
int j = 0; j < m_delim_list.numel (); j++)
3610 if (! m_delim_list(j).is_string ())
3614 if (m_delim_list(j).is_sq_string ())
3619 m_delim_len = std::max (
static_cast<int> (
len),
3625 error (
"%s: Delimiters must be either a string or cell array of strings",
3628 else if (param ==
"commentstyle")
3630 if (args(i+1).is_string ())
3633 m_comment_style =
Cell (args(i+1));
3635 else if (args(i+1).iscell ())
3638 int len = m_comment_style.
numel ();
3639 if ((
len >= 1 && ! m_comment_style (0).is_string ())
3640 || (
len >= 2 && ! m_comment_style (1).is_string ())
3642 error (
"%s: CommentStyle must be either a string or cell array of one or two strings",
3646 error (
"%s: CommentStyle must be either a string or cell array of one or two strings",
3651 if (m_comment_style.numel () >= 1)
3653 m_comment_len = m_comment_style (0).string_value ().size ();
3654 m_comment_char = m_comment_style (0).string_value ()[0];
3657 else if (param ==
"treatasempty")
3659 bool invalid =
false;
3660 if (args(i+1).is_string ())
3662 m_treat_as_empty =
Cell (args(i+1));
3663 m_treat_as_empty_len = args(i+1).string_value ().size ();
3665 else if (args(i+1).iscell ())
3668 for (
int j = 0; j < m_treat_as_empty.numel (); j++)
3669 if (! m_treat_as_empty (j).is_string ())
3673 int k = m_treat_as_empty (j).string_value ().size ();
3674 if (k > m_treat_as_empty_len)
3675 m_treat_as_empty_len = k;
3679 error (
"%s: TreatAsEmpty must be either a string or cell array of one or two strings",
3684 else if (param ==
"collectoutput")
3686 m_collect_output = args(i+1).strict_bool_value (
"%s: CollectOutput must be logical or numeric", m_who.c_str ());
3688 else if (param ==
"emptyvalue")
3690 m_empty_value = args(i+1).xscalar_value (
"%s: EmptyValue must be numeric", m_who.c_str ());
3692 else if (param ==
"headerlines")
3694 m_header_lines = args(i+1).xscalar_value (
"%s: HeaderLines must be numeric", m_who.c_str ());
3696 else if (param ==
"bufsize")
3698 m_buffer_size = args(i+1).xscalar_value (
"%s: BufSize must be numeric", m_who.c_str ());
3700 else if (param ==
"multipledelimsasone")
3702 m_multiple_delims_as_one = args(i+1).strict_bool_value (
"%s: MultipleDelimsAsOne must be logical or numeric", m_who.c_str ());
3704 else if (param ==
"returnonerror")
3706 m_return_on_error = args(i+1).strict_bool_value (
"%s: ReturnOnError must be logical or numeric", m_who.c_str ());
3708 else if (param ==
"whitespace")
3710 m_whitespace = args(i+1).xstring_value (
"%s: Whitespace must be a character string", m_who.c_str ());
3712 else if (param ==
"expchars")
3714 m_exp_chars = args(i+1).xstring_value (
"%s: ExpChars must be a character string", m_who.c_str ());
3715 m_default_exp =
false;
3717 else if (param ==
"endofline")
3720 std::string s = args(i+1).xstring_value (R
"(%s: EndOfLine must be at most one character or '\r\n')",
3722 if (args(i+1).is_sq_string ())
3724 int l = s.length ();
3726 m_eol1 = m_eol2 = -2;
3728 m_eol1 = m_eol2 = s.c_str ()[0];
3731 m_eol1 = s.c_str ()[0];
3732 m_eol2 = s.c_str ()[1];
3733 if (m_eol1 !=
'\r' || m_eol2 !=
'\n')
3740 error (R
"(%s: EndOfLine must be at most one character or '\r\n')",
3744 error (
"%s: unrecognized option '%s'", m_who.c_str (), param.c_str ());
3748 for (
unsigned int j = 0; j < m_delims.length (); j++)
3750 m_whitespace.erase (std::remove (m_whitespace.begin (),
3751 m_whitespace.end (),
3753 m_whitespace.end ());
3755 for (
int j = 0; j < m_delim_list.numel (); j++)
3757 std::string delim = m_delim_list(j).string_value ();
3758 if (delim.length () == 1)
3759 m_whitespace.erase (std::remove (m_whitespace.begin (),
3760 m_whitespace.end (),
3762 m_whitespace.end ());
3765 m_whitespace_table = std::string (256,
'\0');
3766 for (
unsigned int i = 0; i < m_whitespace.length (); i++)
3767 m_whitespace_table[m_whitespace[i]] =
'1';
3771 if (! (m_whitespace.empty () && fmt_list.has_string))
3772 m_whitespace_table[
' '] =
'1';
3775 m_delim_table = std::string (256,
'\0');
3776 if (m_eol1 >= 0 && m_eol1 < 256)
3777 m_delim_table[m_eol1] =
'1';
3778 if (m_eol2 >= 0 && m_eol2 < 256)
3779 m_delim_table[m_eol2] =
'1';
3781 for (
unsigned int i = 0; i < 256; i++)
3784 m_delim_table[i] =
'1';
3787 for (
unsigned int i = 0; i < m_delims.length (); i++)
3788 m_delim_table[m_delims[i]] =
'1';
3795textscan::skip_whitespace (delimited_stream& is,
bool EOLstop)
3797 int c1 = std::istream::traits_type::eof ();
3798 bool found_comment =
false;
3802 found_comment =
false;
3805 && (c1 = is.get_undelim ()) != std::istream::traits_type::eof ()
3806 && ( ( (c1 == m_eol1 || c1 == m_eol2) && ++m_lines && ! EOLstop)
3809 if (prev == m_eol1 && m_eol1 != m_eol2 && c1 == m_eol2)
3814 if (c1 == m_comment_char)
3817 char *pos = is.tellg ();
3818 std::ios::iostate state = is.rdstate ();
3820 std::string tmp (m_comment_len,
'\0');
3821 char *look = is.read (&tmp[0], m_comment_len-1, pos);
3822 if (is && m_comment_style.numel () > 0
3823 && !
strncmp (m_comment_style(0).string_value ().substr (1).c_str (),
3824 look, m_comment_len-1))
3826 found_comment =
true;
3829 if (m_comment_style.numel () == 1)
3831 std::string eol (3,
'\0');
3835 scan_caret (is, eol, dummy);
3836 c1 = is.get_undelim ();
3837 if (c1 == m_eol1 && m_eol1 != m_eol2
3838 && is.peek_undelim () == m_eol2)
3844 std::string end_c = m_comment_style(1).string_value ();
3846 std::string last = end_c.substr (end_c.size () - 1);
3847 std::string may_match (
"");
3851 scan_caret (is, last, dummy);
3854 may_match = may_match + dummy + last;
3855 if (may_match.length () > end_c.length ())
3857 std::size_t start = may_match.length ()
3859 may_match = may_match.substr (start);
3862 while (may_match != end_c && is && ! is.eof ());
3872 while (found_comment);
3874 if (c1 != std::istream::traits_type::eof ())
3885textscan::lookahead (delimited_stream& is,
const Cell& targets,
int max_len,
3886 bool case_sensitive)
const
3892 char *pos = is.tellg ();
3894 std::string tmp (max_len,
'\0');
3895 char *look = is.read (&tmp[0], tmp.size (), pos);
3902 int (*compare)(
const char *,
const char *, std::size_t);
3905 for (i = 0; i < targets.
numel (); i++)
3907 std::string s = targets (i).string_value ();
3908 if (! (*compare) (s.c_str (), look, s.size ()))
3910 is.read (&tmp[0], s.size (), pos);
3915 if (i == targets.
numel ())
3923textscan::skip_delim (delimited_stream& is)
3925 int c1 = skip_whitespace (is);
3926 if (m_delim_list.numel () == 0)
3928 if (is_delim (c1) || c1 == m_eol1 || c1 == m_eol2)
3931 if (c1 == m_eol1 && is.peek_undelim () == m_eol2)
3934 if (m_multiple_delims_as_one)
3940 while (is && ((c1 = is.get_undelim ())
3941 != std::istream::traits_type::eof ())
3942 && (((c1 == m_eol1 || c1 == m_eol2) && ++m_lines)
3943 || isspace (c1) || is_delim (c1)))
3945 if (prev == m_eol1 && m_eol1 != m_eol2 && c1 == m_eol2)
3949 if (c1 != std::istream::traits_type::eof ())
3958 if (c1 == m_eol1 || c1 == m_eol2
3959 || (-1 != (first_match = lookahead (is, m_delim_list, m_delim_len))))
3964 if (is.peek_undelim () == m_eol2)
3967 else if (c1 == m_eol2)
3972 if (m_multiple_delims_as_one)
3978 while (is && ((c1 = skip_whitespace (is))
3979 != std::istream::traits_type::eof ())
3980 && (((c1 == m_eol1 || c1 == m_eol2) && ++m_lines)
3981 || -1 != lookahead (is, m_delim_list, m_delim_len)))
3983 if (prev == m_eol1 && m_eol1 != m_eol2 && c1 == m_eol2)
3999textscan::match_literal (delimited_stream& is,
4000 const textscan_format_elt& fmt)
4004 skip_whitespace (is,
false);
4006 for (
unsigned int i = 0; i < fmt.width; i++)
4008 int ch = is.get_undelim ();
4009 if (ch != fmt.text[i])
4011 if (ch != std::istream::traits_type::eof ())
4013 is.setstate (std::ios::failbit);
4031#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC
4032# pragma GCC diagnostic push
4033# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
4038class wbuffer_u8_converter :
public converter
4042 using converter::wbuffer_convert;
4044#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC
4045# pragma GCC diagnostic pop
4054base_stream::create_converter_stream ()
4058 if (os && *os && ! m_converter)
4061 =
new wbuffer_u8_converter
4066 = std::unique_ptr<std::ostream> (
new std::ostream (m_converter));
4069 return (m_conv_ostream ? m_conv_ostream.get () :
output_stream ());
4083 m_errmsg = who +
": " + msg;
4111 bool strip_newline,
const std::string& who)
4116 ::error (
"%s: unable to read from stdin while running interactively",
4128 invalid_operation (who,
"reading");
4132 std::istream& is = *isp;
4134 std::ostringstream buf;
4141 while (is && (c = is.get ()) != std::istream::traits_type::eof ())
4148 if (! strip_newline)
4149 buf << static_cast<char> (c);
4153 if (c != std::istream::traits_type::eof ())
4159 if (! strip_newline)
4160 buf << static_cast<char> (c);
4170 if (! strip_newline)
4171 buf << static_cast<char> (c);
4176 buf << static_cast<char> (c);
4178 if (max_len > 0 && char_count == max_len)
4183 if (! is.eof () && char_count > 0)
4188 int disgusting_compatibility_hack = is.get ();
4190 is.putback (disgusting_compatibility_hack);
4193 if (is.good () || (is.eof () && char_count > 0))
4195 retval = buf.str ();
4197 retval = string::u8_from_encoding (who, retval,
encoding ());
4203 if (is.eof () && char_count == 0)
4204 error (who,
"at end of file");
4206 error (who,
"read error");
4215 const std::string& who)
4217 return do_gets (max_len, err,
true, who);
4222 const std::string& who)
4224 return do_gets (max_len, err,
false, who);
4228base_stream::skipl (off_t num,
bool& err,
const std::string& who)
4233 ::error (
"%s: unable to read from stdin while running interactively",
4245 invalid_operation (who,
"reading");
4249 std::istream& is = *isp;
4255 while (is && (c = is.get ()) != std::istream::traits_type::eof ())
4258 if (c ==
'\r' || (c ==
'\n' && lastc !=
'\r'))
4268 if (c ==
'\r' && is.peek () ==
'\n')
4274 error (who,
"read error");
4284template <
typename T>
4286octave_scan_1 (std::istream& is,
const scanf_format_elt& fmt,
4292 std::streampos pos = is.tellg ();
4297 is >> std::oct >> value >> std::dec;
4302 is >> std::hex >> value >> std::dec;
4309 if (c1 != std::istream::traits_type::eof ())
4313 int c2 = is.peek ();
4315 if (c2 ==
'x' || c2 ==
'X')
4318 if (std::isxdigit (is.peek ()))
4319 is >> std::hex >> value >> std::dec;
4325 if (c2 ==
'0' || c2 ==
'1' || c2 ==
'2'
4326 || c2 ==
'3' || c2 ==
'4' || c2 ==
'5'
4327 || c2 ==
'6' || c2 ==
'7')
4328 is >> std::oct >> value >> std::dec;
4329 else if (c2 ==
'8' || c2 ==
'9')
4356 std::ios::iostate status = is.rdstate ();
4357 if (! (status & std::ios::failbit))
4371 is.clear (status & ~std::ios::failbit);
4380 is.setstate (status & ~std::ios_base::eofbit);
4387template <
typename T>
4389octave_scan (std::istream& is,
const scanf_format_elt& fmt, T *valptr)
4397 auto orig_pos = is.tellg ();
4399 is.width (fmt.width);
4402 std::istringstream ss (strbuf);
4404 octave_scan_1 (ss, fmt, valptr);
4415 is.seekg (orig_pos, is.beg);
4417 int chars_read = ss.tellg ();
4420 is.width (chars_read);
4427 is.setstate (std::ios::failbit);
4431 octave_scan_1 (is, fmt, valptr);
4438octave_scan<> (std::istream& is,
const scanf_format_elt& fmt,
double *valptr)
4450 std::streampos pos = is.tellg ();
4452 double value = read_value<double> (is);
4454 std::ios::iostate status = is.rdstate ();
4455 if (! (status & std::ios::failbit))
4466 is.setstate (status & ~std::ios_base::eofbit);
4472 error (
"expecting format type to be one of 'e', 'f', 'g', 'E', or 'G' but found '%c' - please report this bug", fmt.type);
4479template <
typename T>
4481do_scanf_conv (std::istream& is,
const scanf_format_elt& fmt,
4486 octave_scan (is, fmt, valptr);
4491 if (idx == max_size && ! discard)
4496 mval.
resize (nr, max_size / nr, 0.0);
4498 mval.
resize (max_size, 1, 0.0);
4506 data[idx++] = *(valptr);
4511do_scanf_conv (std::istream&,
const scanf_format_elt&,
double *,
4515#define DO_WHITESPACE_CONVERSION() \
4518 int c = std::istream::traits_type::eof (); \
4521 while (is && (c = is.get ()) != std::istream::traits_type::eof () \
4525 if (c == std::istream::traits_type::eof ()) \
4527 is.clear (is.rdstate () & (~std::ios::failbit)); \
4534#define DO_LITERAL_CONVERSION() \
4537 int c = std::istream::traits_type::eof (); \
4539 int n = fmt.length (); \
4542 while (i < n && is \
4543 && (c = is.get ()) != std::istream::traits_type::eof ()) \
4545 if (c == static_cast<unsigned char> (fmt[i])) \
4558 is.setstate (std::ios::failbit); \
4562#define DO_PCT_CONVERSION() \
4565 int c = is.get (); \
4567 if (c != std::istream::traits_type::eof ()) \
4572 is.setstate (std::ios::failbit); \
4576 is.setstate (std::ios::failbit); \
4580#define BEGIN_C_CONVERSION() \
4581 is.unsetf (std::ios::skipws); \
4583 int width = (elt->width ? elt->width : 1); \
4585 std::string tmp (width, '\0'); \
4587 int c = std::istream::traits_type::eof (); \
4590 while (is && n < width \
4591 && (c = is.get ()) != std::istream::traits_type::eof ()) \
4592 tmp[n++] = static_cast<char> (c); \
4594 if (c == std::istream::traits_type::eof ()) \
4595 is.clear (is.rdstate () & (~std::ios::failbit)); \
4601#define BEGIN_S_CONVERSION() \
4602 int width = elt->width; \
4610 tmp = std::string (width, '\0'); \
4612 int c = std::istream::traits_type::eof (); \
4616 while (is && (c = is.get ()) != std::istream::traits_type::eof ()) \
4618 if (! isspace (c)) \
4620 tmp[n++] = static_cast<char> (c); \
4625 while (is && n < width \
4626 && (c = is.get ()) != std::istream::traits_type::eof ()) \
4634 tmp[n++] = static_cast<char> (c); \
4637 if (c == std::istream::traits_type::eof ()) \
4638 is.clear (is.rdstate () & (~std::ios::failbit)); \
4644 is >> std::ws >> tmp; \
4650#define BEGIN_CHAR_CLASS_CONVERSION() \
4651 int width = (elt->width ? elt->width \
4652 : std::numeric_limits<int>::max ()); \
4658 std::ostringstream buf; \
4660 std::string char_class = elt->char_class; \
4662 int c = std::istream::traits_type::eof (); \
4664 if (elt->type == '[') \
4666 int chars_read = 0; \
4667 while (is && chars_read++ < width \
4668 && (c = is.get ()) != std::istream::traits_type::eof ()) \
4670 if (char_class.find (c) != std::string::npos) \
4671 buf << static_cast<char> (c); \
4681 int chars_read = 0; \
4682 while (is && chars_read++ < width \
4683 && (c = is.get ()) != std::istream::traits_type::eof ()) \
4685 if (char_class.find (c) == std::string::npos) \
4686 buf << static_cast<char> (c); \
4698 is.setstate (std::ios::failbit); \
4699 else if (c == std::istream::traits_type::eof ()) \
4700 is.clear (is.rdstate () & (~std::ios::failbit)); \
4705#define FINISH_CHARACTER_CONVERSION() \
4708 if (encoding ().compare ("utf-8")) \
4709 tmp = string::u8_from_encoding (who, tmp, encoding ()); \
4710 width = tmp.length (); \
4712 if (is && width > 0) \
4718 conversion_count++; \
4722 if (data_index == max_size) \
4726 if (all_char_conv) \
4728 if (one_elt_size_spec) \
4729 mval.resize (1, max_size, 0.0); \
4731 mval.resize (nr, max_size / nr, 0.0); \
4733 error ("unexpected size in character conversion - please report this bug"); \
4736 mval.resize (nr, max_size / nr, 0.0); \
4738 mval.resize (max_size, 1, 0.0); \
4740 data = mval.rwdata (); \
4743 data[data_index++] = static_cast<unsigned char> \
4752base_stream::do_scanf (scanf_format_list& fmt_list,
4754 bool one_elt_size_spec,
4756 const std::string& who)
4761 ::error (
"%s: unable to read from stdin while running interactively",
4766 conversion_count = 0;
4772 if (nr == 0 || nc == 0)
4774 if (one_elt_size_spec)
4777 return Matrix (nr, nc, 0.0);
4782 bool all_char_conv = fmt_list.all_character_conversions ();
4795 if (one_elt_size_spec)
4798 mval.
resize (1, max_size, 0.0);
4807 mval.
resize (nr, nc, 0.0);
4808 max_size = max_conv = nr * nc;
4812 mval.
resize (nr, 32, 0.0);
4817 error (
"unexpected size in character conversion - please report this bug");
4824 mval.
resize (nr, nc, 0.0);
4826 max_conv = max_size;
4831 mval.
resize (nr, 32, 0.0);
4838 mval.
resize (32, 1, 0.0);
4842 double *data = mval.
rwdata ();
4846 std::istream& is = *isp;
4848 const scanf_format_elt *elt = fmt_list.first ();
4850 std::ios::fmtflags flags = is.flags ();
4862 if (elt->type == scanf_format_elt::null
4863 || (! (elt->type == scanf_format_elt::whitespace_conversion
4864 || elt->type == scanf_format_elt::literal_conversion
4865 || elt->type ==
'%')
4866 && max_conv > 0 && conversion_count == max_conv))
4873 if (all_char_conv && one_elt_size_spec)
4876 final_nc = data_index;
4881 final_nc = (data_index - 1) / nr + 1;
4886 else if (data_index == max_size)
4892 if (one_elt_size_spec)
4893 mval.
resize (1, max_size, 0.0);
4895 mval.
resize (nr, max_size / nr, 0.0);
4897 error (
"unexpected size in character conversion - please report this bug");
4900 mval.
resize (nr, max_size / nr, 0.0);
4902 mval.
resize (max_size, 1, 0.0);
4907 std::string fmt = elt->text;
4909 bool discard = elt->discard;
4913 case scanf_format_elt::whitespace_conversion:
4917 case scanf_format_elt::literal_conversion:
4927 switch (elt->modifier)
4932 do_scanf_conv (is, *elt, &tmp, mval, data,
4933 data_index, conversion_count,
4934 nr, max_size, discard);
4941 do_scanf_conv (is, *elt, &tmp, mval, data,
4942 data_index, conversion_count,
4943 nr, max_size, discard);
4950 do_scanf_conv (is, *elt, &tmp, mval, data,
4951 data_index, conversion_count,
4952 nr, max_size, discard);
4959 case 'o':
case 'u':
case 'x':
case 'X':
4961 switch (elt->modifier)
4966 do_scanf_conv (is, *elt, &tmp, mval, data,
4967 data_index, conversion_count,
4968 nr, max_size, discard);
4975 do_scanf_conv (is, *elt, &tmp, mval, data,
4976 data_index, conversion_count,
4977 nr, max_size, discard);
4984 do_scanf_conv (is, *elt, &tmp, mval, data,
4985 data_index, conversion_count,
4986 nr, max_size, discard);
4993 case 'e':
case 'f':
case 'g':
4998 do_scanf_conv (is, *elt, &tmp, mval, data,
4999 data_index, conversion_count,
5000 nr, max_size, discard);
5031 error (who,
"unsupported format specifier");
5035 error (who,
"internal format error");
5043 else if (is.eof () || ! is)
5047 if (one_elt_size_spec)
5050 final_nc = data_index;
5052 else if (data_index > nr)
5055 final_nc = (data_index - 1) / nr + 1;
5059 final_nr = data_index;
5065 if (data_index > nr)
5068 final_nc = (data_index - 1) / nr + 1;
5072 final_nr = data_index;
5078 final_nr = data_index;
5084 if (is.rdstate () & std::ios::failbit)
5086 is.clear (is.rdstate () & (~std::ios::failbit));
5087 error (who,
"format failed to match");
5093 &&
name () ==
"stdin")
5099 do_gets (-1, err,
false, who);
5107 error (who,
"internal format error");
5111 if (m_nconv == 0 && ++trips == num_fmt_elts)
5113 if (all_char_conv && one_elt_size_spec)
5116 final_nc = data_index;
5121 final_nc = (data_index - 1) / nr + 1;
5132 elt = fmt_list.next (m_nconv > 0
5134 || conversion_count < max_conv));
5139 mval.
resize (final_nr, final_nc, 0.0);
5150base_stream::scanf (
const std::string& fmt,
const Array<double>& size,
5152 const std::string& who)
5156 conversion_count = 0;
5161 invalid_operation (who,
"reading");
5164 scanf_format_list fmt_list (fmt);
5166 if (fmt_list.num_conversions () == -1)
5167 ::error (
"%s: invalid format specified", who.c_str ());
5172 bool one_elt_size_spec;
5174 get_size (size, nr, nc, one_elt_size_spec, who);
5176 retval = do_scanf (fmt_list, nr, nc, one_elt_size_spec,
5177 conversion_count, who);
5184base_stream::do_oscanf (
const scanf_format_elt *elt,
5194 std::istream& is = *isp;
5196 std::ios::fmtflags flags = is.flags ();
5200 std::string fmt = elt->text;
5202 bool discard = elt->discard;
5206 case scanf_format_elt::whitespace_conversion:
5210 case scanf_format_elt::literal_conversion:
5225 switch (elt->modifier)
5230 if (octave_scan (is, *elt, &tmp))
5243 if (octave_scan (is, *elt, &tmp))
5256 if (octave_scan (is, *elt, &tmp))
5269 case 'o':
case 'u':
case 'x':
case 'X':
5271 switch (elt->modifier)
5276 if (octave_scan (is, *elt, &tmp))
5289 if (octave_scan (is, *elt, &tmp))
5302 if (octave_scan (is, *elt, &tmp))
5315 case 'e':
case 'f':
case 'g':
5320 if (octave_scan (is, *elt, &tmp))
5370 error (who,
"unsupported format specifier");
5374 error (who,
"internal format error");
5379 if (
ok () && is.fail ())
5381 error (
"%s: read error", who.c_str ());
5388 &&
name () ==
"stdin")
5392 do_gets (-1, err,
false, who);
5400base_stream::oscanf (
const std::string& fmt,
const std::string& who)
5407 invalid_operation (who,
"reading");
5410 std::istream& is = *isp;
5412 scanf_format_list fmt_list (fmt);
5417 ::error (
"%s: invalid format specified", who.c_str ());
5425 const scanf_format_elt *elt = fmt_list.first ();
5435 quit = do_oscanf (elt, tmp, who);
5442 retval(num_values++) = tmp;
5447 elt = fmt_list.next (m_nconv > 0);
5451 retval(m_nconv) = num_values;
5454 retval(m_nconv+1) =
error (
false, err_num);
5459 if (
ok () &&
len > m_nconv)
5463 elt = fmt_list.next ();
5465 do_oscanf (elt, tmp, who);
5474base_stream::do_textscan (
const std::string& fmt,
5477 const std::string& who,
5483 ::error (
"%s: unable to read from stdin while running interactively",
5491 invalid_operation (who,
"reading");
5496 retval =
scanner.scan (*isp, fmt, ntimes, options, read_count);
5506base_stream::flush ()
5513 invalid_operation (
"fflush",
"writing");
5525class printf_value_cache
5529 enum state { ok, conversion_error };
5532 : m_values (args), m_val_idx (0), m_elt_idx (0),
5533 m_n_vals (m_values.length ()), m_n_elts (0), m_have_data (false),
5545 OCTAVE_DISABLE_COPY_MOVE (printf_value_cache)
5547 ~printf_value_cache () =
default;
5558 operator bool ()
const {
return (m_curr_state == ok); }
5560 bool exhausted () {
return (m_val_idx >= m_n_vals); }
5565 printf_value_cache ();
5580printf_value_cache::get_next_value (
char type)
5585 m_curr_state = conversion_error;
5587 while (! exhausted ())
5591 m_curr_val = m_values (m_val_idx);
5594 m_n_elts = m_curr_val.numel ();
5598 if (m_elt_idx < m_n_elts)
5602 if (m_curr_val.is_string ())
5609 retval = sval.substr (m_elt_idx);
5612 m_elt_idx = m_n_elts;
5622 for (; idx < m_n_elts; idx++)
5624 double dval = val(idx);
5626 if (! math::is_integer (dval)
5627 || dval < 0 || dval > 255)
5635 std::string sval (n,
'\0');
5638 sval[i] = val(m_elt_idx++);
5650 if (type ==
'c' && ! retval.
is_string ())
5654 if (math::is_integer (dval) && dval >= 0 && dval < 256)
5655 retval =
static_cast<char> (dval);
5659 if (m_elt_idx >= m_n_elts)
5663 m_have_data =
false;
5671 m_have_data =
false;
5677 if (type ==
's' || type ==
'c')
5686 m_curr_state = conversion_error;
5695printf_value_cache::int_value ()
5701 if (dval < 0 || dval > std::numeric_limits<int>::max ()
5702 || ! math::is_integer (dval))
5704 m_curr_state = conversion_error;
5708 return math::nint (dval);
5713template <
typename T>
5715do_printf_conv (std::ostream& os,
const char *fmt,
int nsa,
int sa_1,
5716 int sa_2, T arg,
const std::string& who)
5723 retval =
format (os, fmt, sa_1, sa_2, arg);
5727 retval =
format (os, fmt, sa_1, arg);
5731 retval =
format (os, fmt, arg);
5735 ::error (
"%s: internal error handling format", who.c_str ());
5743do_printf_string (std::ostream& os,
const printf_format_elt *elt,
5744 int nsa,
int sa_1,
int sa_2,
const std::string& arg,
5745 const std::string& who)
5748 ::error (
"%s: internal error handling format", who.c_str ());
5750 std::string flags = elt->flags;
5752 bool left = flags.find (
'-') != std::string::npos;
5754 std::size_t
len = arg.length ();
5756 std::size_t prec = (nsa > 1 ? sa_2 : (elt->prec == -1 ?
len : elt->prec));
5758 std::string print_str = prec < arg.length () ? arg.substr (0, prec) : arg;
5760 std::size_t fw = (nsa > 0 ? sa_1 : (elt->fw == -1 ?
len : elt->fw));
5762 os << std::setw (fw) << (left ? std::left : std::right) << print_str;
5764 return len > fw ?
len : fw;
5779 uint64_t limit = std::numeric_limits<int64_t>::max ();
5789 if (ival.
value () <= limit)
5799 if (dval == math::fix (dval) && dval <= limit)
5818 return ov_is_ge_zero.
is_true ();
5824 uint64_t limit = std::numeric_limits<uint64_t>::max ();
5826 if (dval == math::fix (dval) && dval >= 0 && dval <= limit)
5834switch_to_g_format (
const printf_format_elt *elt)
5836 std::string tfmt = elt->text;
5838 tfmt.replace (tfmt.rfind (elt->type), 1,
"g");
5844base_stream::do_numeric_printf_conv (std::ostream& os,
5845 const printf_format_elt *elt,
5846 int nsa,
int sa_1,
int sa_2,
5848 const std::string& who)
5852 std::string tfmt = elt->text;
5854 if (is_nan_or_inf (val))
5858 std::string::size_type i1, i2;
5860 tfmt.replace ((i1 = tfmt.rfind (elt->type)), 1, 1,
's');
5862 if ((i2 = tfmt.rfind (
'.')) != std::string::npos && i2 < i1)
5864 tfmt.erase (i2, i1-i2);
5865 if (elt->prec == -2)
5870 if (math::isinf (dval))
5872 if (elt->flags.find (
'+') != std::string::npos)
5873 tval = (dval < 0 ?
"-Inf" :
"+Inf");
5875 tval = (dval < 0 ?
"-Inf" :
"Inf");
5879 if (elt->flags.find (
'+') != std::string::npos)
5885 retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2, tval,
5890 static std::string llmod
5891 = (
sizeof (long) ==
sizeof (int64_t) ?
"l" :
"ll");
5893 char type = elt->type;
5897 case 'd':
case 'i':
case 'c':
5898 if (ok_for_signed_int_conv (val))
5903 tfmt.replace (tfmt.rfind (type), 1, llmod + type);
5905 retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2,
5906 tval.
value (), who);
5910 tfmt = switch_to_g_format (elt);
5914 retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2,
5919 case 'o':
case 'x':
case 'X':
case 'u':
5920 if (ok_for_unsigned_int_conv (val))
5925 tfmt.replace (tfmt.rfind (type), 1, llmod + type);
5927 retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2,
5928 tval.
value (), who);
5932 tfmt = switch_to_g_format (elt);
5936 retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2,
5941 case 'f':
case 'e':
case 'E':
5946 retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2,
5954 error (who,
"invalid format specifier");
5964base_stream::field_width_error (
const std::string& who)
const
5966 ::error (
"%s: invalid field width, must be integer >= 0 and <= INT_MAX",
5971base_stream::do_printf (printf_format_list& fmt_list,
5973 const std::string& who)
5982 invalid_operation (who,
"writing");
5985 std::ostream& os = *osp;
5989 const printf_format_elt *elt = fmt_list.first ();
5991 printf_value_cache val_cache (args, who);
5998 ::error (
"%s: internal error handling format", who.c_str ());
6001 int nsa = (elt->fw == -2) + (elt->prec == -2);
6008 sa_1 = val_cache.int_value ();
6012 field_width_error (who);
6019 sa_2 = val_cache.int_value ();
6023 field_width_error (who);
6030 if (elt->type ==
'%')
6035 else if (elt->args == 0 && ! elt->text.empty ())
6038 retval += (elt->text.length ());
6040 else if (elt->type ==
's' || elt->type ==
'c')
6042 octave_value val = val_cache.get_next_value (elt->type);
6050 retval += do_printf_string (os, elt, nsa, sa_1,
6054 retval += do_numeric_printf_conv (os, elt, nsa, sa_1,
6067 retval += do_numeric_printf_conv (os, elt, nsa, sa_1,
6076 error (who,
"write error");
6080 elt = fmt_list.next (m_nconv > 0 && ! val_cache.exhausted ());
6082 if (! elt || (val_cache.exhausted () && elt->args > 0))
6091base_stream::printf (
const std::string& fmt,
6093 const std::string& who)
6095 printf_format_list fmt_list (fmt);
6097 if (fmt_list.num_conversions () == -1)
6098 ::error (
"%s: invalid format specified", who.c_str ());
6100 return do_printf (fmt_list, args, who);
6104base_stream::puts (
const std::string& s,
const std::string& who)
6111 invalid_operation (who,
"writing");
6114 std::ostream& os = *osp;
6119 error (who,
"write error");
6133 error (who,
"write error");
6145 err_num = (m_fail ? -1 : 0);
6147 std::string tmp = m_errmsg;
6156base_stream::invalid_operation (
const std::string& who,
const char *rw)
6159 error (who, std::string (
"stream not open for ") + rw);
6168 retval = m_rep->flush ();
6179 retval = m_rep->getl (max_len, err, who);
6186 const std::string& who)
6196 max_len = convert_to_valid_int (tc_max_len, conv_err);
6198 if (conv_err || max_len < 0)
6201 ::error (
"%s: invalid maximum length specified", who.c_str ());
6205 return getl (max_len, err, who);
6214 retval = m_rep->gets (max_len, err, who);
6221 const std::string& who)
6231 max_len = convert_to_valid_int (tc_max_len, conv_err);
6233 if (conv_err || max_len < 0)
6236 ::error (
"%s: invalid maximum length specified", who.c_str ());
6240 return gets (max_len, err, who);
6249 retval = m_rep->skipl (count, err, who);
6256 const std::string& who)
6271 count = convert_to_valid_int (tc_count, conv_err);
6273 if (conv_err || count < 0)
6276 ::error (
"%s: invalid number of lines specified",
6282 return skipl (count, err, who);
6295 off_t orig_pos = m_rep->tell ();
6298 status = m_rep->seek (0,
SEEK_END);
6302 off_t eof_pos = m_rep->tell ();
6314 status = m_rep->seek (offset, origin);
6319 off_t desired_pos = m_rep->tell ();
6323 if (desired_pos > eof_pos || desired_pos < 0)
6354 off_t xoffset = val.
value ();
6362 std::string xorigin = tc_origin.
xstring_value (
"fseek: invalid value for origin");
6364 if (xorigin ==
"bof")
6366 else if (xorigin ==
"cof")
6368 else if (xorigin ==
"eof")
6375 int xorigin = convert_to_valid_int (tc_origin, conv_err);
6381 else if (xorigin == 0)
6383 else if (xorigin == 1)
6391 ::error (
"fseek: invalid value for origin");
6393 retval =
seek (xoffset, origin);
6397 error (
"fseek: failed to seek to requested position");
6408 retval = m_rep->tell ();
6422 bool retval =
false;
6425 retval = m_rep->is_open ();
6440template <
typename SRC_T,
typename DST_T>
6442convert_and_copy (std::list<void *>& input_buf_list,
6446 bool do_float_fmt_conv,
bool do_NA_conv,
6447 mach_info::float_format from_flt_fmt)
6449 typedef typename DST_T::element_type dst_elt_type;
6453 dst_elt_type *conv_data = conv.rwdata ();
6457 for (
auto it = input_buf_list.cbegin (); it != input_buf_list.cend (); it++)
6459 SRC_T *data =
static_cast<SRC_T *
> (*it);
6461 if (swap || do_float_fmt_conv)
6469 swap_bytes<sizeof (SRC_T)> (&data[i]);
6470 else if (do_float_fmt_conv)
6473 mach_info::native_float_format ());
6482 conv_data[j] = data[i];
6491 swap_bytes<sizeof (SRC_T)> (&data[i]);
6492 else if (do_float_fmt_conv)
6495 mach_info::native_float_format ());
6497 conv_data[j] = data[i];
6509 conv_data[j] = data[i];
6516 conv_data[j] = data[i];
6523 input_buf_list.clear ();
6526 conv_data[i] = dst_elt_type (0);
6534 bool swap,
bool do_float_fmt_conv,
bool do_NA_conv,
6535 mach_info::float_format from_flt_fmt);
6537#define TABLE_ELT(T, U, V, W) \
6538 conv_fptr_table[oct_data_conv::T][oct_data_conv::U] = convert_and_copy<V, W>
6540#define FILL_TABLE_ROW(T, V) \
6541 TABLE_ELT (T, dt_int8, V, int8NDArray); \
6542 TABLE_ELT (T, dt_uint8, V, uint8NDArray); \
6543 TABLE_ELT (T, dt_int16, V, int16NDArray); \
6544 TABLE_ELT (T, dt_uint16, V, uint16NDArray); \
6545 TABLE_ELT (T, dt_int32, V, int32NDArray); \
6546 TABLE_ELT (T, dt_uint32, V, uint32NDArray); \
6547 TABLE_ELT (T, dt_int64, V, int64NDArray); \
6548 TABLE_ELT (T, dt_uint64, V, uint64NDArray); \
6549 TABLE_ELT (T, dt_single, V, FloatNDArray); \
6550 TABLE_ELT (T, dt_double, V, NDArray); \
6551 TABLE_ELT (T, dt_char, V, charNDArray); \
6552 TABLE_ELT (T, dt_schar, V, charNDArray); \
6553 TABLE_ELT (T, dt_uchar, V, charNDArray); \
6554 TABLE_ELT (T, dt_logical, V, boolNDArray);
6557stream::finalize_read (std::list<void *>& input_buf_list,
6563 mach_info::float_format ffmt)
6567 static bool initialized =
false;
6576 for (
int j = 0; j < 14; j++)
6577 conv_fptr_table[i][j] =
nullptr;
6599 if (ffmt == mach_info::flt_fmt_unknown)
6602 if (mach_info::words_big_endian ())
6603 swap = (ffmt == mach_info::flt_fmt_ieee_little_endian);
6605 swap = (ffmt == mach_info::flt_fmt_ieee_big_endian);
6613 switch (output_type)
6632 retval =
fptr (input_buf_list, input_buf_elts, elts_read,
6633 nr, nc, swap, do_float_fmt_conv, do_NA_conv, ffmt);
6638 ::error (
"read: invalid type specification");
6659 bool one_elt_size_spec =
false;
6667 std::ptrdiff_t tmp_count = 0;
6671 get_size (size, nr, nc, one_elt_size_spec,
"fread");
6675 invalid_operation (
"fread",
"reading");
6680 if (one_elt_size_spec)
6703 if (nr == 0 || nc == 0)
6709 bool read_to_eof = elts_to_read < 0;
6716 input_buf_elts = 1024 * 1024;
6718 input_buf_elts = elts_to_read;
6721 input_buf_elts = block_size;
6726 std::ptrdiff_t input_buf_size
6727 =
static_cast<std::ptrdiff_t
> (input_buf_elts) * input_elt_size;
6735 error (
"fread: invalid input stream");
6738 std::istream& is = *isp;
6743 if (skip != 0 && is && ! is.eof ())
6745 cur_pos = is.tellg ();
6746 is.seekg (0, is.end);
6747 eof_pos = is.tellg ();
6748 is.seekg (cur_pos, is.beg);
6751 std::list<void *> input_buf_list;
6753 while (is && ! is.eof ()
6754 && (read_to_eof || tmp_count < elts_to_read))
6760 if (remaining_elts < input_buf_elts)
6761 input_buf_size = remaining_elts * input_elt_size;
6764 char *input_buf =
new char [input_buf_size];
6766 is.read (input_buf, input_buf_size);
6768 std::size_t gcount = is.gcount ();
6776 input_buf_list.push_back (input_buf);
6778 if (skip != 0 && nel == block_size && is)
6782 off_t remaining = eof_pos - cur_pos;
6784 if (remaining < skip)
6786 is.seekg (0, is.end);
6791 is.seekg (skip, is.cur);
6801 nc = tmp_count / nr;
6803 if (tmp_count % nr != 0)
6809 else if (tmp_count == 0)
6814 else if (tmp_count != nr * nc)
6816 if (tmp_count % nr != 0)
6817 nc = tmp_count / nr + 1;
6819 nc = tmp_count / nr;
6825 if (tmp_count > std::numeric_limits<octave_idx_type>::max ())
6826 error (
"fread: number of elements read exceeds max index size");
6830 retval = finalize_read (input_buf_list, input_buf_elts, count,
6831 nr, nc, input_type, output_type, ffmt);
6845 invalid_operation (
"fwrite",
"writing");
6848 if (flt_fmt == mach_info::flt_fmt_unknown)
6855 error (
"fwrite: write error");
6863template <
typename T,
typename V>
6865convert_chars (
const void *data,
void *conv_data,
octave_idx_type n_elts)
6867 const T *tt_data =
static_cast<const T *
> (data);
6869 V *vt_data =
static_cast<V *
> (conv_data);
6872 vt_data[i] = tt_data[i];
6875template <
typename T,
typename V>
6880 typedef typename V::val_type val_type;
6882 val_type *vt_data =
static_cast<val_type *
> (conv_data);
6889 vt_data[i] = val.value ();
6892 swap_bytes<sizeof (val_type)> (&vt_data[i]);
6896template <
typename T>
6897class ultimate_element_type
6903template <
typename T>
6910template <
typename T>
6914 mach_info::float_format flt_fmt)
6920 if (mach_info::words_big_endian ())
6921 swap = (flt_fmt == mach_info::flt_fmt_ieee_little_endian);
6923 swap = (flt_fmt == mach_info::flt_fmt_ieee_big_endian);
6925 bool do_float_conversion = flt_fmt != mach_info::float_format ();
6927 typedef typename ultimate_element_type<T>::type ult_elt_type;
6929 switch (output_type)
6932 convert_chars<ult_elt_type, char> (data, conv_data, n_elts);
6936 convert_chars<ult_elt_type, signed char> (data, conv_data, n_elts);
6940 convert_chars<ult_elt_type, unsigned char> (data, conv_data, n_elts);
6944 convert_ints<T, octave_int8> (data, conv_data, n_elts, swap);
6948 convert_ints<T, octave_uint8> (data, conv_data, n_elts, swap);
6952 convert_ints<T, octave_int16> (data, conv_data, n_elts, swap);
6956 convert_ints<T, octave_uint16> (data, conv_data, n_elts, swap);
6960 convert_ints<T, octave_int32> (data, conv_data, n_elts, swap);
6964 convert_ints<T, octave_uint32> (data, conv_data, n_elts, swap);
6968 convert_ints<T, octave_int64> (data, conv_data, n_elts, swap);
6972 convert_ints<T, octave_uint64> (data, conv_data, n_elts, swap);
6977 float *vt_data =
static_cast<float *
> (conv_data);
6981 vt_data[i] = data[i];
6983 if (do_float_conversion)
6991 double *vt_data =
static_cast<double *
> (conv_data);
6995 vt_data[i] = data[i];
6997 if (do_float_conversion)
7004 ::error (
"write: invalid type specification");
7013 bool status =
false;
7019 std::ostream& os = *osp;
7023 os.write (
static_cast<const char *
> (data), nbytes);
7036 bool status =
false;
7043 std::ostream& os = *osp;
7047 off_t orig_pos =
tell ();
7051 off_t eof_pos =
tell ();
7056 std::size_t remaining = eof_pos - orig_pos;
7058 if (remaining < skip)
7063 unsigned char zero = 0;
7064 for (std::size_t j = 0; j < skip - remaining; j++)
7065 os.write (
reinterpret_cast<const char *
> (&zero), 1);
7076template <
typename T>
7081 mach_info::float_format flt_fmt)
7085 if (mach_info::words_big_endian ())
7086 swap = (flt_fmt == mach_info::flt_fmt_ieee_little_endian);
7088 swap = (flt_fmt == mach_info::flt_fmt_ieee_big_endian);
7090 bool do_data_conversion = (swap || ! is_equivalent_type<T> (output_type)
7091 || flt_fmt != mach_info::float_format ());
7098 chunk_size = block_size;
7099 else if (do_data_conversion)
7100 chunk_size = 1024 * 1024;
7106 const T *pdata = data.
data ();
7118 if (chunk_size > remaining_nel)
7119 chunk_size = remaining_nel;
7121 bool status =
false;
7123 if (do_data_conversion)
7125 std::size_t output_size
7130 status = convert_data (&pdata[i], conv_data, chunk_size,
7131 output_type, flt_fmt);
7137 status =
write_bytes (pdata,
sizeof (T) * chunk_size);
7148#define INSTANTIATE_WRITE(T) \
7150 OCTINTERP_API octave_idx_type \
7151 stream::write (const Array<T>& data, octave_idx_type block_size, \
7152 oct_data_conv::data_type output_type, \
7153 octave_idx_type skip, \
7154 mach_info::float_format flt_fmt)
7173#if defined (OCTAVE_HAVE_OVERLOAD_CHAR_INT8_TYPES)
7186 retval = m_rep->scanf (fmt, size, count, who);
7204 retval =
scanf (sfmt, size, count, who);
7209 error (who +
": format must be a string");
7221 retval = m_rep->oscanf (fmt, who);
7238 retval =
oscanf (sfmt, who);
7243 error (who +
": format must be a string");
7254 return (stream_ok ()
7255 ? m_rep->do_textscan (fmt, ntimes, options, who, count)
7261 const std::string& who)
7266 retval = m_rep->printf (fmt, args, who);
7273 const std::string& who)
7284 retval =
printf (sfmt, args, who);
7289 error (who +
": format must be a string");
7301 retval = m_rep->puts (s, who);
7316 retval =
puts (s, who);
7321 error (who +
": argument must be a string");
7333 retval = m_rep->eof ();
7341 std::string retval =
"invalid stream object";
7343 if (stream_ok (
false))
7344 retval = m_rep->error (clear, err_num);
7355 retval = m_rep->name ();
7366 retval = m_rep->mode ();
7371mach_info::float_format
7374 mach_info::float_format retval = mach_info::flt_fmt_unknown;
7377 retval = m_rep->float_format ();
7385 std::string retval =
"???";
7386 std::ios::openmode in_mode =
static_cast<std::ios::openmode
> (
mode);
7388 if (in_mode == std::ios::in)
7390 else if (in_mode == std::ios::out
7391 || in_mode == (std::ios::out | std::ios::trunc))
7393 else if (in_mode == (std::ios::out | std::ios::app))
7395 else if (in_mode == (std::ios::in | std::ios::out))
7397 else if (in_mode == (std::ios::in | std::ios::out | std::ios::trunc))
7399 else if (in_mode == (std::ios::in | std::ios::out | std::ios::ate))
7401 else if (in_mode == (std::ios::in | std::ios::binary))
7403 else if (in_mode == (std::ios::out | std::ios::binary)
7404 || in_mode == (std::ios::out | std::ios::trunc | std::ios::binary))
7406 else if (in_mode == (std::ios::out | std::ios::app | std::ios::binary))
7408 else if (in_mode == (std::ios::in | std::ios::out | std::ios::binary))
7410 else if (in_mode == (std::ios::in | std::ios::out | std::ios::trunc
7411 | std::ios::binary))
7413 else if (in_mode == (std::ios::in | std::ios::out | std::ios::ate
7414 | std::ios::binary))
7421 : m_list (), m_lookup_cache (m_list.end ()), m_stdin_file (-1),
7422 m_stdout_file (-1), m_stderr_file (-1)
7438 m_stdin_file =
insert (stdin_stream);
7439 m_stdout_file =
insert (stdout_stream);
7440 m_stderr_file =
insert (stderr_stream);
7455 if (stream_number == -1)
7456 return stream_number;
7471 if (m_list.size () >= m_list.max_size ())
7472 ::error (
"could not create file id");
7474 m_list[stream_number] = os;
7476 return stream_number;
7479OCTAVE_NORETURN
static void
7480err_invalid_file_id (
int fid,
const std::string& who)
7483 ::error (
"invalid stream number = %d", fid);
7485 ::error (
"%s: invalid stream number = %d", who.c_str (), fid);
7494 err_invalid_file_id (fid, who);
7496 if (m_lookup_cache != m_list.end () && m_lookup_cache->first == fid)
7497 retval = m_lookup_cache->second;
7500 ostrl_map::const_iterator iter = m_list.find (fid);
7502 if (iter == m_list.end ())
7503 err_invalid_file_id (fid, who);
7505 retval = iter->second;
7506 m_lookup_cache = iter;
7525 err_invalid_file_id (fid, who);
7527 auto iter = m_list.find (fid);
7529 if (iter == m_list.end ())
7530 err_invalid_file_id (fid, who);
7532 stream os = iter->second;
7533 m_list.erase (iter);
7534 m_lookup_cache = m_list.end ();
7538 err_invalid_file_id (fid, who);
7560 retval =
remove (i, who);
7576 for (
auto iter = m_list.begin (); iter != m_list.end (); )
7578 int fid = iter->first;
7585 stream os = iter->second;
7587 std::string name = os.
name ();
7588 std::transform (name.begin (), name.end (), name.begin (), tolower);
7591 if (name.find (
"gnuplot") != std::string::npos)
7602 m_list.erase (iter++);
7605 m_lookup_cache = m_list.end ();
7617 if (m_lookup_cache != m_list.end () && m_lookup_cache->first == fid)
7618 os = m_lookup_cache->second;
7621 ostrl_map::const_iterator iter = m_list.find (fid);
7623 if (iter == m_list.end ())
7627 m_lookup_cache = iter;
7633 retval(0) = os.
name ();
7635 retval(2) = mach_info::float_format_as_string (os.
float_format ());
7647 ::error (
"file id must be a file object or integer value");
7649 int int_fid = convert_to_valid_int (fid, conv_err);
7652 ::error (
"file id must be a file object or integer value");
7660 std::ostringstream buf;
7663 <<
" number mode arch name\n"
7664 <<
" ------ ---- ---- ----\n";
7666 for (
const auto& fid_strm : m_list)
7668 stream os = fid_strm.second;
7671 << std::setiosflags (std::ios::right)
7672 << std::setw (4) << fid_strm.first <<
" "
7674 << std::resetiosflags (std::ios::adjustfield)
7675 << std::setiosflags (std::ios::left)
7680 << mach_info::float_format_as_string (os.
float_format ())
7682 << os.
name () <<
"\n";
7693 Matrix retval (1, m_list.size (), 0.0);
7697 for (
const auto& fid_strm : m_list)
7700 if (fid_strm.first > 2 && fid_strm.second)
7701 retval(0, num_open++) = fid_strm.first;
7704 retval.
resize ((num_open > 0), num_open);
7718 for (
const auto& fid_strm : m_list)
7721 if (fid_strm.first > 2)
7723 stream os = fid_strm.second;
7725 if (os && os.
name () == nm)
7727 retval = fid_strm.first;
7734 ::error (
"file id must be a file object, std::string, or integer value");
7739 int int_fid = convert_to_valid_int (fid, conv_err);
7742 ::error (
"file id must be a file object, std::string, or integer value");
7768OCTAVE_END_NAMESPACE(octave)
N Dimensional Array with copy-on-write semantics.
const T * data() const
Size of the specified dimension.
T * rwdata()
Size of the specified dimension.
octave_idx_type numel() const
Number of elements in the array.
void resize(octave_idx_type nr, octave_idx_type nc, double rfv=0)
static bool forced_interactive()
std::ostream * preferred_output_stream()
virtual std::string name() const =0
std::string encoding() const
virtual std::ostream * output_stream()
virtual std::istream * input_stream()
std::string error(bool clear, int &err_num)
virtual int file_number() const
Vector representing the dimensions (size) of an Array.
output_system & get_output_system()
void recover_from_exception()
static stream create(std::istream *arg=nullptr, const std::string &n="")
static std::size_t data_type_size(data_type dt)
virtual bool fast_elem_insert(octave_idx_type n, const octave_value &x)
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
octave_idx_type length() const
octave_value isinf() const
octave_uint64 uint64_scalar_value() const
octave_int64 int64_scalar_value() const
bool is_scalar_type() const
bool is_sq_string() const
bool is_single_type() const
octave_value isnan() const
bool is_uint64_type() const
octave_value reshape(const dim_vector &dv) const
octave_int64 xint64_scalar_value(const char *fmt,...) const
double scalar_value(bool frc_str_conv=false) const
octave_value fast_elem_extract(octave_idx_type n) const
Extract the n-th element, aka 'val(n)'.
std::string string_value(bool force=false) const
NDArray array_value(bool frc_str_conv=false) const
int write(octave::stream &os, int block_size, oct_data_conv::data_type output_type, int skip, octave::mach_info::float_format flt_fmt) const
octave_value convert_to_str(bool pad=false, bool force=false, char type='\'') const
std::string xstring_value(const char *fmt,...) const
double double_value(bool frc_str_conv=false) const
octave_base_value * internal_rep() const
static stream create(std::ostream *arg, const std::string &n="")
std::ostream & __stdout__()
octave_value stdin_file() const
int get_file_number(const octave_value &fid) const
std::string list_open_files() const
octave_value stdout_file() const
stream_list(interpreter &interp)
stream lookup(int fid, const std::string &who="") const
octave_value open_file_numbers() const
string_vector get_info(int fid) const
int remove(int fid, const std::string &who="")
void clear(bool flush=true)
octave_value stderr_file() const
std::ostream * output_stream()
std::istream * input_stream()
static std::string mode_as_string(int mode)
octave_value scanf(const std::string &fmt, const Array< double > &size, octave_idx_type &count, const std::string &who)
std::string gets(octave_idx_type max_len, bool &err, const std::string &who)
bool skip_bytes(std::size_t n_elts)
off_t skipl(off_t count, bool &err, const std::string &who)
octave_value textscan(const std::string &fmt, octave_idx_type ntimes, const octave_value_list &options, const std::string &who, octave_idx_type &count)
int puts(const std::string &s, const std::string &who)
int printf(const std::string &fmt, const octave_value_list &args, const std::string &who)
bool write_bytes(const void *data, std::size_t n_elts)
mach_info::float_format float_format() const
int seek(off_t offset, int origin)
octave_value_list oscanf(const std::string &fmt, const std::string &who)
std::string getl(octave_idx_type max_len, bool &err, const std::string &who)
std::string error(bool clear, int &err_num)
octave_value read(const Array< double > &size, octave_idx_type block_size, oct_data_conv::data_type input_type, oct_data_conv::data_type output_type, octave_idx_type skip, mach_info::float_format flt_fmt, octave_idx_type &count)
octave_idx_type write(const octave_value &data, octave_idx_type block_size, oct_data_conv::data_type output_type, octave_idx_type skip, mach_info::float_format flt_fmt)
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void do_float_format_conversion(void *data, octave_idx_type len, octave::mach_info::float_format from_fmt, octave::mach_info::float_format to_fmt)
void do_double_format_conversion(void *data, octave_idx_type len, octave::mach_info::float_format from_fmt, octave::mach_info::float_format to_fmt)
void warning(const char *fmt,...)
void warning_with_id(const char *id, const char *fmt,...)
void error(const char *fmt,...)
void err_wrong_type_arg(const char *name, const char *s)
interpreter & __get_interpreter__()
F77_RET_T const F77_INT const F77_INT const F77_INT const F77_DBLE const F77_DBLE F77_INT F77_DBLE * V
std::complex< double > w(std::complex< double > z, double relerr=0)
std::complex< double > Complex
std::complex< float > FloatComplex
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
FloatComplex(* fptr)(const FloatComplex &, float, int, octave_idx_type &)
#define BEGIN_S_CONVERSION()
std::wbuffer_convert< convfacet_u8, char > converter
#define BEGIN_CHAR_CLASS_CONVERSION()
#define BEGIN_C_CONVERSION()
#define DO_WHITESPACE_CONVERSION()
string::deletable_facet< string::codecvt_u8 > convfacet_u8
#define DO_LITERAL_CONVERSION()
octave_value(* conv_fptr)(std::list< void * > &input_buf_list, octave_idx_type input_buf_elts, octave_idx_type elts_read, octave_idx_type nr, octave_idx_type nc, bool swap, bool do_float_fmt_conv, bool do_NA_conv, mach_info::float_format from_flt_fmt)
#define FILL_TABLE_ROW(T, V)
#define INSTANTIATE_WRITE(T)
#define DO_PCT_CONVERSION()
#define FINISH_CHARACTER_CONVERSION()
T::size_type numel(const T &str)
bool strncmp(const T &str_a, const T &str_b, const typename T::size_type n)
True if the first N characters are the same.
const octave_base_value const Array< octave_idx_type > & ra_idx
octave_value cat_op(type_info &ti, const octave_value &a, const octave_value &b, const Array< octave_idx_type > &ra_idx)
octave_value binary_op(type_info &ti, octave_value::binary_op op, const octave_value &a, const octave_value &b)
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x
F77_RET_T const F77_DBLE const F77_DBLE * f
int octave_strncasecmp(const char *s1, const char *s2, size_t n)
std::string do_string_escapes(const std::string &s)
std::string undo_string_escapes(const std::string &s)
std::size_t format(std::ostream &os, const char *fmt,...)