From 9087cd7b8e2e477b436700bcbb130654a3311321 Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@Germany> Date: Mon, 19 Jan 2009 11:33:37 +0100 Subject: [PATCH] Support for single-quoted strings - token class handles both single and double quoted strings. Single quoted strings are used to tag regular expressions. At the moment this is just syntactical sugar and isn't (yet) treated differently than double-quoted strings. - write output for std:string, with/without single quotes with the method writeQuoted(). Use distinct method name to avoid inadvertent compiler conversions. - write wordRe and keyType using writeQuoted() --- src/OpenFOAM/db/IOstreams/IOstreams/Ostream.C | 13 +-- src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H | 8 ++ src/OpenFOAM/db/IOstreams/Pstreams/OPstream.C | 12 +++ src/OpenFOAM/db/IOstreams/Pstreams/OPstream.H | 8 ++ src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C | 92 +++++++++--------- src/OpenFOAM/db/IOstreams/Sstreams/OSstream.C | 94 +++++++++++++++---- src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H | 8 ++ .../db/IOstreams/Sstreams/prefixOSstream.C | 11 +++ .../db/IOstreams/Sstreams/prefixOSstream.H | 8 ++ .../IOstreams/StringStreams/IStringStream.H | 1 + .../IOstreams/StringStreams/OStringStream.H | 3 +- src/OpenFOAM/db/IOstreams/token/token.H | 47 +++++----- .../primitives/strings/fileName/fileNameI.H | 7 +- src/OpenFOAM/primitives/strings/word/wordI.H | 13 +-- .../primitives/strings/wordRe/wordRe.H | 2 +- .../primitives/strings/wordRe/wordReIO.C | 11 +-- 16 files changed, 228 insertions(+), 110 deletions(-) diff --git a/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.C b/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.C index 18a93e93bcb..c0d1a035359 100644 --- a/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.C +++ b/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.C @@ -48,17 +48,11 @@ void Foam::Ostream::decrIndent() // Write keyType +// write regular expression as single-quoted string +// write plain word as word (unquoted) Foam::Ostream& Foam::Ostream::write(const keyType& kw) { - // Write as word or string - if (kw.isPattern()) - { - return write(static_cast<const string&>(kw)); - } - else - { - return write(static_cast<const word&>(kw)); - } + return writeQuoted(kw, kw.isPattern()); } @@ -76,6 +70,7 @@ Foam::Ostream& Foam::Ostream::writeKeyword(const keyType& kw) nSpaces -= 2; } + // could also increment by indentSize_ ... if (nSpaces < 1) { nSpaces = 1; diff --git a/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H b/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H index 30ecf298dc7..6d01d46438d 100644 --- a/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H +++ b/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H @@ -115,6 +115,14 @@ public: //- Write string virtual Ostream& write(const string&) = 0; + //- Write std::string surrounded by single quotes. + // Optional write without quotes. + virtual Ostream& writeQuoted + ( + const std::string&, + const bool quoted=true + ) = 0; + //- Write label virtual Ostream& write(const label) = 0; diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/OPstream.C b/src/OpenFOAM/db/IOstreams/Pstreams/OPstream.C index 8e754ce2fd5..1cfcd9eec68 100644 --- a/src/OpenFOAM/db/IOstreams/Pstreams/OPstream.C +++ b/src/OpenFOAM/db/IOstreams/Pstreams/OPstream.C @@ -175,6 +175,18 @@ Foam::Ostream& Foam::OPstream::write(const string& str) } +Foam::Ostream& Foam::OPstream::writeQuoted(const std::string& str, const bool) +{ + write(char(token::STRING)); + + size_t len = str.size(); + writeToBuffer(len); + writeToBuffer(str.c_str(), len + 1, 1); + + return *this; +} + + Foam::Ostream& Foam::OPstream::write(const label val) { write(char(token::LABEL)); diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/OPstream.H b/src/OpenFOAM/db/IOstreams/Pstreams/OPstream.H index 075f7c557c4..b02f892d9e2 100644 --- a/src/OpenFOAM/db/IOstreams/Pstreams/OPstream.H +++ b/src/OpenFOAM/db/IOstreams/Pstreams/OPstream.H @@ -136,6 +136,14 @@ public: //- Write string Ostream& write(const string&); + //- Write std::string surrounded by single quotes. + // Optional write without quotes. + Ostream& writeQuoted + ( + const std::string&, + const bool quoted=true + ); + //- Write label Ostream& write(const label); diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C index c2e27d5d165..c94e6c9bbcb 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C +++ b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C @@ -152,8 +152,9 @@ Foam::Istream& Foam::ISstream::read(token& t) return *this; } - // Strings: enclosed by double quotes. + // Strings: enclosed by single or double quotes. case token::BEGIN_STRING : + case token::BEGIN_QSTRING : { putback(c); string* sPtr = new string; @@ -366,7 +367,13 @@ Foam::Istream& Foam::ISstream::read(string& str) return *this; } - if (c != token::BEGIN_STRING) + char endTok = token::END_STRING; + + if (c == token::BEGIN_QSTRING) + { + endTok = token::END_QSTRING; + } + else if (c != token::BEGIN_STRING) { buf[0] = '\0'; @@ -382,52 +389,49 @@ Foam::Istream& Foam::ISstream::read(string& str) while (get(c)) { - switch (c) + if (c == endTok) { - case token::END_STRING : - if (escaped) - { - escaped = false; - i--; // overwrite backslash - } - else - { - // done reading string - buf[i] = '\0'; - str = buf; - return *this; - } - break; - - case token::NL : - if (escaped) - { - escaped = false; - i--; // overwrite backslash - } - else - { - buf[i] = '\0'; - buf[errLen] = '\0'; - - FatalIOErrorIn("ISstream::read(string&)", *this) - << "found '\\n' while reading string \"" - << buf << "...\"" - << exit(FatalIOError); - - return *this; - } - break; - - case '\\': - escaped = !escaped; // toggle state (retains backslashes) - break; - - default: + if (escaped) + { escaped = false; - break; + i--; // overwrite backslash + } + else + { + // done reading string + buf[i] = '\0'; + str = buf; + return *this; + } } + else if (c == token::NL) + { + if (escaped) + { + escaped = false; + i--; // overwrite backslash + } + else + { + buf[i] = '\0'; + buf[errLen] = '\0'; + FatalIOErrorIn("ISstream::read(string&)", *this) + << "found '\\n' while reading string \"" + << buf << "...\"" + << exit(FatalIOError); + + return *this; + } + } + else if (c == '\\') + { + escaped = !escaped; // toggle state (retains backslashes) + } + else + { + escaped = false; + } buf[i] = c; if (i++ == maxLen) diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.C b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.C index 5c60ada59f8..a954f1b778b 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.C +++ b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.C @@ -74,28 +74,26 @@ Foam::Ostream& Foam::OSstream::write(const string& str) { register char c = *iter; - switch (c) + if (c == '\\') { - case '\\' : - backslash++; - // suppress output until we know if other characters follow - continue; - break; - - case token::NL : - lineNumber_++; - backslash++; // backslash escape for newline - break; - - case token::END_STRING : - backslash++; // backslash escape for double-quote - break; + backslash++; + // suppress output until we know if other characters follow + continue; + } + else if (c == token::NL) + { + lineNumber_++; + backslash++; // backslash escape for newline + } + else if (c == token::END_STRING) + { + backslash++; // backslash escape for quote } // output pending backslashes while (backslash) { - os_ << '\\'; // escape for new-line + os_ << '\\'; backslash--; } @@ -103,7 +101,7 @@ Foam::Ostream& Foam::OSstream::write(const string& str) } // silently drop any trailing backslashes - // they would otherwise appear like an escaped double-quote + // they would otherwise appear like an escaped end-quote os_ << token::END_STRING; @@ -112,6 +110,68 @@ Foam::Ostream& Foam::OSstream::write(const string& str) } +Foam::Ostream& Foam::OSstream::writeQuoted +( + const std::string& str, + const bool quoted +) +{ + if (quoted) + { + os_ << token::BEGIN_QSTRING; + + register int backslash = 0; + for + ( + string::const_iterator iter = str.begin(); + iter != str.end(); + ++iter + ) + { + register char c = *iter; + + if (c == '\\') + { + backslash++; + // suppress output until we know if other characters follow + continue; + } + else if (c == token::NL) + { + lineNumber_++; + backslash++; // backslash escape for newline + } + else if (c == token::END_QSTRING) + { + backslash++; // backslash escape for quote + } + + // output pending backslashes + while (backslash) + { + os_ << '\\'; + backslash--; + } + + os_ << c; + } + + // silently drop any trailing backslashes + // they would otherwise appear like an escaped end-quote + os_ << token::END_QSTRING; + } + else + { + // output unquoted string, only advance line number on newline + lineNumber_ += string(str).count(token::NL); + os_ << str; + } + + setState(os_.rdstate()); + return *this; +} + + Foam::Ostream& Foam::OSstream::write(const label val) { os_ << val; diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H index 816021f8c52..d4f552bd532 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H +++ b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H @@ -141,6 +141,14 @@ public: // double-quote. virtual Ostream& write(const string&); + //- Write std::string surrounded by single quotes. + // Optional write without quotes. + virtual Ostream& writeQuoted + ( + const std::string&, + const bool quoted=true + ); + //- Write label virtual Ostream& write(const label); diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/prefixOSstream.C b/src/OpenFOAM/db/IOstreams/Sstreams/prefixOSstream.C index 79aa6d5a03a..9d6b740b7eb 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/prefixOSstream.C +++ b/src/OpenFOAM/db/IOstreams/Sstreams/prefixOSstream.C @@ -115,6 +115,17 @@ Foam::Ostream& Foam::prefixOSstream::write(const string& val) } +Foam::Ostream& Foam::prefixOSstream::writeQuoted +( + const std::string& val, + const bool quoted +) +{ + checkWritePrefix(); + return OSstream::writeQuoted(val, quoted); +} + + Foam::Ostream& Foam::prefixOSstream::write(const label val) { checkWritePrefix(); diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/prefixOSstream.H b/src/OpenFOAM/db/IOstreams/Sstreams/prefixOSstream.H index 85e909bdcbf..aede82b4b94 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/prefixOSstream.H +++ b/src/OpenFOAM/db/IOstreams/Sstreams/prefixOSstream.H @@ -114,6 +114,14 @@ public: //- Write string virtual Ostream& write(const string&); + //- Write std::string + // Specify if string should be single quoted or remain unquoted. + virtual Ostream& writeQuoted + ( + const std::string&, + const bool quoted=true + ); + //- Write label virtual Ostream& write(const label); diff --git a/src/OpenFOAM/db/IOstreams/StringStreams/IStringStream.H b/src/OpenFOAM/db/IOstreams/StringStreams/IStringStream.H index 760b4cfed13..d7e9995e9be 100644 --- a/src/OpenFOAM/db/IOstreams/StringStreams/IStringStream.H +++ b/src/OpenFOAM/db/IOstreams/StringStreams/IStringStream.H @@ -105,6 +105,7 @@ public: // Access + //- Return the string string str() const { return dynamic_cast<const std::istringstream&>(stream()).str(); diff --git a/src/OpenFOAM/db/IOstreams/StringStreams/OStringStream.H b/src/OpenFOAM/db/IOstreams/StringStreams/OStringStream.H index c50ac7babc5..8f76748292f 100644 --- a/src/OpenFOAM/db/IOstreams/StringStreams/OStringStream.H +++ b/src/OpenFOAM/db/IOstreams/StringStreams/OStringStream.H @@ -57,7 +57,7 @@ public: // Constructors - //- Set stream status + //- Construct and set stream status OStringStream ( streamFormat format=ASCII, @@ -106,6 +106,7 @@ public: // Access + //- Return the string string str() const { return dynamic_cast<const std::ostringstream&>(stream()).str(); diff --git a/src/OpenFOAM/db/IOstreams/token/token.H b/src/OpenFOAM/db/IOstreams/token/token.H index b2657395725..9cd5bde737d 100644 --- a/src/OpenFOAM/db/IOstreams/token/token.H +++ b/src/OpenFOAM/db/IOstreams/token/token.H @@ -92,28 +92,31 @@ public: //- Standard punctuation tokens enum punctuationToken { - NULL_TOKEN = '\0', - SPACE = ' ', - TAB = '\t', - NL = '\n', - - END_STATEMENT = ';', - BEGIN_LIST = '(', - END_LIST = ')', - BEGIN_SQR = '[', - END_SQR = ']', - BEGIN_BLOCK = '{', - END_BLOCK = '}', - COLON = ':', - COMMA = ',', - BEGIN_STRING = '"', - END_STRING = '"', - - ASSIGN = '=', - ADD = '+', - SUBTRACT = '-', - MULTIPLY = '*', - DIVIDE = '/' + NULL_TOKEN = '\0', + SPACE = ' ', + TAB = '\t', + NL = '\n', + + END_STATEMENT = ';', + BEGIN_LIST = '(', + END_LIST = ')', + BEGIN_SQR = '[', + END_SQR = ']', + BEGIN_BLOCK = '{', + END_BLOCK = '}', + COLON = ':', + COMMA = ',', + + BEGIN_STRING = '"', + END_STRING = BEGIN_STRING, + BEGIN_QSTRING = '\'', + END_QSTRING = BEGIN_QSTRING, + + ASSIGN = '=', + ADD = '+', + SUBTRACT = '-', + MULTIPLY = '*', + DIVIDE = '/' }; diff --git a/src/OpenFOAM/primitives/strings/fileName/fileNameI.H b/src/OpenFOAM/primitives/strings/fileName/fileNameI.H index f2fb48345be..d8b03fe645c 100644 --- a/src/OpenFOAM/primitives/strings/fileName/fileNameI.H +++ b/src/OpenFOAM/primitives/strings/fileName/fileNameI.H @@ -94,7 +94,12 @@ inline Foam::fileName::fileName(const char* str) inline bool Foam::fileName::valid(char c) { - return (!isspace(c) && c != '"'); + return + ( + !isspace(c) + && c != '"' // string quote + && c != '\'' // string quote + ); } diff --git a/src/OpenFOAM/primitives/strings/word/wordI.H b/src/OpenFOAM/primitives/strings/word/wordI.H index f84b99be437..b1daf2752c7 100644 --- a/src/OpenFOAM/primitives/strings/word/wordI.H +++ b/src/OpenFOAM/primitives/strings/word/wordI.H @@ -119,12 +119,13 @@ inline bool Foam::word::valid(char c) { return ( - !isspace(c) - && c != '"' - && c != '/' - && c != ';' - && c != '{' - && c != '}' + !isspace(c) + && c != '"' // string quote + && c != '\'' // string quote + && c != '/' // path separator + && c != ';' // end statement + && c != '{' // beg subdict + && c != '}' // end subdict ); } diff --git a/src/OpenFOAM/primitives/strings/wordRe/wordRe.H b/src/OpenFOAM/primitives/strings/wordRe/wordRe.H index 3eec24b2b25..aee6c3a883f 100644 --- a/src/OpenFOAM/primitives/strings/wordRe/wordRe.H +++ b/src/OpenFOAM/primitives/strings/wordRe/wordRe.H @@ -91,7 +91,7 @@ public: // Note that 'REGEXP' is implicit if 'NOCASE' is specified alone. enum compOption { - LITERAL = 0, /*!< treat as a strign literal */ + LITERAL = 0, /*!< treat as a string literal */ DETECT = 1, /*!< treat as regular expression */ REGEXP = 2, /*!< detect if the string contains meta-characters */ NOCASE = 4, /*!< ignore case in regular expression */ diff --git a/src/OpenFOAM/primitives/strings/wordRe/wordReIO.C b/src/OpenFOAM/primitives/strings/wordRe/wordReIO.C index 49bfd17ddf5..dab1542b276 100644 --- a/src/OpenFOAM/primitives/strings/wordRe/wordReIO.C +++ b/src/OpenFOAM/primitives/strings/wordRe/wordReIO.C @@ -78,14 +78,7 @@ Foam::Istream& Foam::operator>>(Istream& is, wordRe& w) Foam::Ostream& Foam::operator<<(Ostream& os, const wordRe& w) { - if (w.isPattern()) - { - os.write(static_cast<const string&>(w)); - } - else - { - os.write(static_cast<const word&>(w)); - } + os.writeQuoted(w, w.isPattern()); os.check("Ostream& operator<<(Ostream&, const wordRe&)"); return os; } @@ -99,7 +92,7 @@ Foam::Ostream& Foam::wordRe::info(Ostream& os) const } else { - os << "wordRe(plain) '" << *this << "'"; + os << "wordRe(plain) \"" << *this << '"'; } os.flush(); -- GitLab