Skips whitespace (including lineBreaks, if desired) & comments, then reads one token. A token can be: - a string ("" delimited; ignores readToEOL) - whitespace-delimited (if readToEOL == false) - EOL- or comment-delimited (if readToEOL == true); i.e. reads to end of line or the first // or /* @param text adjusted to start beyond the read token */
| 107 | @param text adjusted to start beyond the read token |
| 108 | */ |
| 109 | static gsl::cstring_view GetToken( gsl::cstring_view& text, bool allowLineBreaks, bool readToEOL = false ) |
| 110 | { |
| 111 | skipWhitespaceAndComments( text, allowLineBreaks ); |
| 112 | // EOF |
| 113 | if ( text.empty() ) |
| 114 | { |
| 115 | return{}; |
| 116 | } |
| 117 | // string. ignores readToEOL. |
| 118 | if ( text[0] == '"' ) |
| 119 | { |
| 120 | // there are no escapes, string just ends at the next " |
| 121 | auto tokenEnd = std::find( text.begin() + 1, text.end(), '"' ); |
| 122 | if ( tokenEnd == text.end() ) |
| 123 | { |
| 124 | gsl::cstring_view token = { text.begin() + 1, text.end() }; |
| 125 | text = { text.end(), text.end() }; |
| 126 | return token; |
| 127 | } |
| 128 | else |
| 129 | { |
| 130 | gsl::cstring_view token = { text.begin() + 1, tokenEnd }; |
| 131 | text = { tokenEnd + 1, text.end() }; |
| 132 | return token; |
| 133 | } |
| 134 | } |
| 135 | else if ( readToEOL ) |
| 136 | { |
| 137 | // find the first of '\n', "//" or "/*"; that's end of token |
| 138 | auto tokenEnd = std::find( text.begin(), text.end(), '\n' ); |
| 139 | static const std::array< char, 2 > commentPatterns[]{ |
| 140 | { { '/', '*' } }, |
| 141 | { { '/', '/' } } |
| 142 | }; |
| 143 | for ( auto& pattern : commentPatterns ) |
| 144 | { |
| 145 | tokenEnd = std::min( |
| 146 | tokenEnd, |
| 147 | std::search( |
| 148 | text.begin(), tokenEnd, |
| 149 | pattern.begin(), pattern.end() |
| 150 | ) |
| 151 | ); |
| 152 | } |
| 153 | gsl::cstring_view token{ text.begin(), tokenEnd }; |
| 154 | text = { tokenEnd, text.end() }; |
| 155 | return removeTrailingWhitespace( token ); |
| 156 | } |
| 157 | else |
| 158 | { |
| 159 | // consume until first whitespace (if allowLineBreaks == false, that may be text.begin(); in that case token is empty.) |
| 160 | auto tokenEnd = std::find_if( text.begin(), text.end(), static_cast< int( *)(int) >(std::isspace) ); |
| 161 | gsl::cstring_view token{ text.begin(), tokenEnd }; |
| 162 | text = { tokenEnd, text.end() }; |
| 163 | return token; |
| 164 | } |
| 165 | } |
| 166 |
no test coverage detected