Mercurial > octave
diff libinterp/corefcn/oct-stream.cc @ 21477:4fc04d04dd9c
make printf and scanf format element and list objects private
* oct-stream.cc (scanf_format_elt, scanf_format_list,
printf_format_elt, printf_format_list): Move class declarations and
definitions here.
* oct-stream.h: From here.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 18 Mar 2016 13:10:19 -0400 |
parents | 4f3e63d75f33 |
children | 7a19c5678f91 |
line wrap: on
line diff
--- a/libinterp/corefcn/oct-stream.cc Fri Mar 18 12:25:23 2016 -0400 +++ b/libinterp/corefcn/oct-stream.cc Fri Mar 18 13:10:19 2016 -0400 @@ -169,6 +169,156 @@ nc = get_size (dnc, who); } +class +scanf_format_elt +{ +public: + + enum special_conversion + { + whitespace_conversion = 1, + literal_conversion = 2, + null = 3 + }; + + scanf_format_elt (const char *txt = 0, int w = 0, bool d = false, + char typ = '\0', char mod = '\0', + const std::string& ch_class = "") + : text (strsave (txt)), width (w), discard (d), type (typ), + modifier (mod), char_class (ch_class) + { } + + scanf_format_elt (const scanf_format_elt& e) + : text (strsave (e.text)), width (e.width), discard (e.discard), + type (e.type), modifier (e.modifier), char_class (e.char_class) + { } + + scanf_format_elt& operator = (const scanf_format_elt& e) + { + if (this != &e) + { + text = strsave (e.text); + width = e.width; + discard = e.discard; + type = e.type; + modifier = e.modifier; + char_class = e.char_class; + } + + return *this; + } + + ~scanf_format_elt (void) { delete [] text; } + + // The C-style format string. + const char *text; + + // The maximum field width. + int width; + + // TRUE if we are not storing the result of this conversion. + bool discard; + + // Type of conversion -- 'd', 'i', 'o', 'u', 'x', 'e', 'f', 'g', + // 'c', 's', 'p', '%', or '['. + char type; + + // A length modifier -- 'h', 'l', or 'L'. + char modifier; + + // The class of characters in a '[' format. + std::string char_class; +}; + +class +scanf_format_list +{ +public: + + scanf_format_list (const std::string& fmt = ""); + + ~scanf_format_list (void); + + octave_idx_type num_conversions (void) { return nconv; } + + // The length can be different than the number of conversions. + // For example, "x %d y %d z" has 2 conversions but the length of + // the list is 3 because of the characters that appear after the + // last conversion. + + size_t length (void) const { return fmt_elts.size (); } + + const scanf_format_elt *first (void) + { + curr_idx = 0; + return current (); + } + + const scanf_format_elt *current (void) const + { + return length () > 0 ? fmt_elts[curr_idx] : 0; + } + + const scanf_format_elt *next (bool cycle = true) + { + static scanf_format_elt dummy + (0, 0, false, scanf_format_elt::null, '\0', ""); + + curr_idx++; + + if (curr_idx >= length ()) + { + if (cycle) + curr_idx = 0; + else + return &dummy; + } + + return current (); + } + + void printme (void) const; + + bool ok (void) const { return (nconv >= 0); } + + operator bool () const { return ok (); } + + bool all_character_conversions (void); + + bool all_numeric_conversions (void); + +private: + + // Number of conversions specified by this format string, or -1 if + // invalid conversions have been found. + octave_idx_type nconv; + + // Index to current element; + size_t curr_idx; + + // List of format elements. + std::deque<scanf_format_elt*> fmt_elts; + + // Temporary buffer. + std::ostringstream *buf; + + void add_elt_to_list (int width, bool discard, char type, char modifier, + const std::string& char_class = ""); + + void process_conversion (const std::string& s, size_t& i, size_t n, + int& width, bool& discard, char& type, + char& modifier); + + int finish_conversion (const std::string& s, size_t& i, size_t n, + int& width, bool discard, char& type, + char modifier); + // No copying! + + scanf_format_list (const scanf_format_list&); + + scanf_format_list& operator = (const scanf_format_list&); +}; + scanf_format_list::scanf_format_list (const std::string& s) : nconv (0), curr_idx (0), fmt_elts (), buf (0) { @@ -578,7 +728,143 @@ return false; } -// Ugh again. +class +printf_format_elt +{ +public: + + printf_format_elt (const char *txt = 0, int n = 0, int w = -1, + int p = -1, const std::string& f = "", + char typ = '\0', char mod = '\0') + : text (strsave (txt)), args (n), fw (w), prec (p), flags (f), + type (typ), modifier (mod) + { } + + printf_format_elt (const printf_format_elt& e) + : text (strsave (e.text)), args (e.args), fw (e.fw), prec (e.prec), + flags (e.flags), type (e.type), modifier (e.modifier) + { } + + printf_format_elt& operator = (const printf_format_elt& e) + { + if (this != &e) + { + text = strsave (e.text); + args = e.args; + fw = e.fw; + prec = e.prec; + flags = e.flags; + type = e.type; + modifier = e.modifier; + } + + return *this; + } + + ~printf_format_elt (void) { delete [] text; } + + // The C-style format string. + const char *text; + + // How many args do we expect to consume? + int args; + + // Field width. + int fw; + + // Precision. + int prec; + + // Flags -- '-', '+', ' ', '0', or '#'. + std::string flags; + + // Type of conversion -- 'd', 'i', 'o', 'x', 'X', 'u', 'c', 's', + // 'f', 'e', 'E', 'g', 'G', 'p', or '%' + char type; + + // A length modifier -- 'h', 'l', or 'L'. + char modifier; +}; + +class +printf_format_list +{ +public: + + printf_format_list (const std::string& fmt = ""); + + ~printf_format_list (void); + + octave_idx_type num_conversions (void) { return nconv; } + + const printf_format_elt *first (void) + { + curr_idx = 0; + return current (); + } + + const printf_format_elt *current (void) const + { + return length () > 0 ? fmt_elts[curr_idx] : 0; + } + + size_t length (void) const { return fmt_elts.size (); } + + const printf_format_elt *next (bool cycle = true) + { + curr_idx++; + + if (curr_idx >= length ()) + { + if (cycle) + curr_idx = 0; + else + return 0; + } + + return current (); + } + + bool last_elt_p (void) { return (curr_idx + 1 == length ()); } + + void printme (void) const; + + bool ok (void) const { return (nconv >= 0); } + + operator bool () const { return ok (); } + +private: + + // Number of conversions specified by this format string, or -1 if + // invalid conversions have been found. + octave_idx_type nconv; + + // Index to current element; + size_t curr_idx; + + // List of format elements. + std::deque<printf_format_elt*> fmt_elts; + + // Temporary buffer. + std::ostringstream *buf; + + void add_elt_to_list (int args, const std::string& flags, int fw, + int prec, char type, char modifier); + + void process_conversion (const std::string& s, size_t& i, size_t n, + int& args, std::string& flags, int& fw, + int& prec, char& modifier, char& type); + + void finish_conversion (const std::string& s, size_t& i, int args, + const std::string& flags, int fw, int prec, + char modifier, char& type); + + // No copying! + + printf_format_list (const printf_format_list&); + + printf_format_list& operator = (const printf_format_list&); +}; printf_format_list::printf_format_list (const std::string& s) : nconv (0), curr_idx (0), fmt_elts (), buf (0)