ISstream.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2017-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "ISstream.H"
30 #include "int.H"
31 #include "token.H"
32 #include <cctype>
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 // Truncate error message for readability
37 static constexpr const unsigned errLen = 80;
38 
39 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
40 
41 namespace
42 {
43 
44 // Convert a single character to a word with length 1
45 inline static Foam::word charToWord(char c)
46 {
47  return Foam::word(std::string(1, c), false);
48 }
49 
50 
51 // Permit slash-scoping of entries
52 static inline bool validVariableChar(char c)
53 {
54  return (Foam::word::valid(c) || c == '/');
55 }
56 
57 } // End anonymous namespace
58 
59 
60 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
61 
62 char Foam::ISstream::nextValid()
63 {
64  char c = 0;
65 
66  while (true)
67  {
68  // Get next non-whitespace character
69  while (get(c) && isspace(c))
70  {}
71 
72  // Return if stream is bad - ie, previous get() failed
73  if (bad() || isspace(c))
74  {
75  return 0;
76  }
77 
78  // Is this the start of a C/C++ comment?
79  if (c == '/')
80  {
81  if (!get(c))
82  {
83  // Cannot get another character - return this one
84  return '/';
85  }
86 
87  if (c == '/')
88  {
89  // C++ style single-line comment - skip through past end-of-line
90  while (get(c) && c != '\n')
91  {}
92  }
93  else if (c == '*')
94  {
95  // Within a C-style comment
96  while (true)
97  {
98  // Search for end of C-style comment - '*/'
99  if (get(c) && c == '*')
100  {
101  if (get(c))
102  {
103  if (c == '/')
104  {
105  // matched '*/'
106  break;
107  }
108  else if (c == '*')
109  {
110  // check again
111  putback(c);
112  }
113  }
114  }
115 
116  if (!good())
117  {
118  return 0;
119  }
120  }
121  }
122  else
123  {
124  // The '/' did not start a C/C++ comment - return it
125  putback(c);
126  return '/';
127  }
128  }
129  else
130  {
131  // A valid character - return it
132  return c;
133  }
134  }
135 
136  return 0;
137 }
138 
139 
140 void Foam::ISstream::readWordToken(token& t)
141 {
142  word val;
143  if (read(val).bad())
144  {
145  t.setBad();
146  }
147  else if (token::compound::isCompound(val))
148  {
149  t = token::compound::New(val, *this).ptr();
150  }
151  else
152  {
153  t = std::move(val); // Move contents to token
154  }
155 }
156 
157 
159 {
160  constexpr const unsigned maxLen = 128; // Max length for labels/scalars
161  static char buf[maxLen];
162 
163  // Return the put back token if it exists
164  if (Istream::getBack(t))
165  {
166  return *this;
167  }
168 
169  // Assume that the streams supplied are in working order.
170  // Lines are counted by '\n'
171 
172  // Get next 'valid character': i.e. proceed through any whitespace
173  // and/or comments until a semantically valid character is found
174 
175  char c = nextValid();
176 
177  // Set the line number of this token to the current stream line number
178  t.lineNumber() = lineNumber();
179 
180  // Return on error
181  if (!c)
182  {
183  t.setBad();
184  return *this;
185  }
186 
187  // Analyse input starting with this character.
188  switch (c)
189  {
190  // Check for punctuation first - same as token::isseparator()
191 
192  case token::END_STATEMENT :
193  case token::BEGIN_LIST :
194  case token::END_LIST :
195  case token::BEGIN_SQR :
196  case token::END_SQR :
197  case token::BEGIN_BLOCK :
198  case token::END_BLOCK :
199  case token::COLON :
200  case token::COMMA :
201  case token::ASSIGN :
202  case token::ADD :
203  // NB: token::SUBTRACT handled later as the possible start of a Number
204  case token::MULTIPLY :
205  case token::DIVIDE :
206  {
208  return *this;
209  }
210 
211  // String: enclosed by double quotes.
212  case token::BEGIN_STRING :
213  {
214  putback(c);
215 
216  string val;
217  if (read(val).bad())
218  {
219  t.setBad();
220  }
221  else
222  {
223  t = std::move(val); // Move contents to token
224  }
225 
226  return *this;
227  }
228 
229  // Possible verbatim string or dictionary functionEntry
230  case token::HASH :
231  {
232  char nextC;
233  if (read(nextC).bad())
234  {
235  // Return lone '#' as word
236  t = charToWord(c);
237  }
238  else if (nextC == token::BEGIN_BLOCK)
239  {
240  // Verbatim string: #{ ... #}
241 
242  string val;
243  if (readVerbatim(val).bad())
244  {
245  t.setBad();
246  }
247  else
248  {
249  t = std::move(val); // Move contents to token
250  t.setType(token::tokenType::VERBATIM);
251  }
252  }
253  else
254  {
255  // Word beginning with '#'. Eg, "#include"
256  // Put back both so that '#...' is included in the directive
257 
258  putback(nextC);
259  putback(c);
260 
261  word val;
262  if (read(val).bad())
263  {
264  t.setBad();
265  }
266  else
267  {
268  t = std::move(val); // Move contents to token
269  t.setType(token::tokenType::DIRECTIVE);
270  }
271  }
272 
273  return *this;
274  }
275 
276  // Dictionary variable (as rvalue)
277  case token::DOLLAR :
278  {
279  char nextC;
280  if (read(nextC).bad())
281  {
282  // Return lone '$' as word
283  t = charToWord(c);
284  }
285  else
286  {
287  // Put back both so that '$...' is included in the variable
288  putback(nextC);
289  putback(c);
290 
291  string val;
292  if (readVariable(val).bad())
293  {
294  t.setBad();
295  }
296  else
297  {
298  t = std::move(val); // Move contents to token
299  t.setType(token::tokenType::VARIABLE);
300  }
301  }
302 
303  return *this;
304  }
305 
306  // Number: integer or floating point
307  //
308  // ideally match the equivalent of this regular expression
309  //
310  // /[-+]?([0-9]+\.?[0-9]*|\.[0-9]+)([Ee][-+]?[0-9]+)?/
311  //
312  case '-' :
313  case '.' :
314  case '0' : case '1' : case '2' : case '3' : case '4' :
315  case '5' : case '6' : case '7' : case '8' : case '9' :
316  {
317  label labelVal = (c != '.'); // used as bool here
318 
319  unsigned nChar = 0;
320  buf[nChar++] = c;
321 
322  // get everything that could resemble a number and let
323  // readScalar determine the validity
324  while
325  (
326  is_.get(c)
327  && (
328  isdigit(c)
329  || c == '+'
330  || c == '-'
331  || c == '.'
332  || c == 'E'
333  || c == 'e'
334  )
335  )
336  {
337  if (labelVal)
338  {
339  labelVal = isdigit(c);
340  }
341 
342  buf[nChar++] = c;
343  if (nChar == maxLen)
344  {
345  // Runaway argument - avoid buffer overflow
346  buf[maxLen-1] = '\0';
347 
349  << "number '" << buf << "...'\n"
350  << " is too long (max. " << maxLen << " characters)"
351  << exit(FatalIOError);
352 
353  t.setBad();
354  return *this;
355  }
356  }
357  buf[nChar] = '\0'; // Terminate string
358 
359  setState(is_.rdstate());
360  if (is_.bad())
361  {
362  t.setBad();
363  }
364  else
365  {
366  is_.putback(c);
367 
368  if (nChar == 1 && buf[0] == '-')
369  {
370  // A single '-' is punctuation
372  }
373  else if (labelVal && Foam::read(buf, labelVal))
374  {
375  t = labelVal;
376  }
377  else
378  {
379  scalar scalarVal;
380 
381  if (readScalar(buf, scalarVal))
382  {
383  // A scalar or too big to fit as a label
384  t = scalarVal;
385  }
386  else
387  {
388  t.setBad();
389  }
390  }
391  }
392 
393  return *this;
394  }
395 
396  // Should be a word (which can also be a single character)
397  default:
398  {
399  putback(c);
400  readWordToken(t);
401 
402  return *this;
403  }
404  }
405 }
406 
407 
409 {
410  c = nextValid();
411  return *this;
412 }
413 
414 
416 {
417  constexpr const unsigned maxLen = 1024;
418  static char buf[maxLen];
419 
420  unsigned nChar = 0;
421  unsigned depth = 0; // Track depth of (..) nesting
422  char c;
423 
424  while
425  (
426  (nChar < maxLen)
427  && get(c)
428  && word::valid(c)
429  )
430  {
431  if (c == token::BEGIN_LIST)
432  {
433  ++depth;
434  }
435  else if (c == token::END_LIST)
436  {
437  if (!depth)
438  {
439  break; // Closed ')' without an opening '(' ? ... stop
440  }
441  --depth;
442  }
443 
444  buf[nChar++] = c;
445  }
446 
447  if (nChar >= maxLen)
448  {
449  buf[errLen] = '\0';
450 
452  << "word '" << buf << "...'\n"
453  << " is too long (max. " << maxLen << " characters)"
454  << exit(FatalIOError);
455 
456  return *this;
457  }
458 
459  buf[nChar] = '\0'; // Terminate string
460 
461  if (bad())
462  {
463  // Could probably skip this check
464  buf[errLen] = '\0';
465 
467  << "Problem while reading word '" << buf << "...' after "
468  << nChar << " characters\n"
469  << exit(FatalIOError);
470 
471  return *this;
472  }
473 
474  if (nChar == 0)
475  {
477  << "Invalid first character found : " << c
478  << exit(FatalIOError);
479  }
480  else if (depth)
481  {
482  IOWarningInFunction(*this)
483  << "Missing " << depth
484  << " closing ')' while parsing" << nl << nl
485  << buf << nl << endl;
486  }
487 
488  // Finalize: content already validated, assign without additional checks.
489  str.assign(buf, nChar);
490  putback(c);
491 
492  return *this;
493 }
494 
495 
497 {
498  constexpr const unsigned maxLen = 1024;
499  static char buf[maxLen];
500 
501  char c;
502 
503  if (!get(c))
504  {
506  << "cannot read start of string"
507  << exit(FatalIOError);
508 
509  return *this;
510  }
511 
512  // Note, we could also handle single-quoted strings here (if desired)
513  if (c != token::BEGIN_STRING)
514  {
516  << "Incorrect start of string character found : " << c
517  << exit(FatalIOError);
518 
519  return *this;
520  }
521 
522  unsigned nChar = 0;
523  bool escaped = false;
524 
525  while
526  (
527  (nChar < maxLen)
528  && get(c)
529  )
530  {
531  if (c == token::END_STRING)
532  {
533  if (escaped)
534  {
535  escaped = false;
536  --nChar; // Overwrite backslash
537  }
538  else
539  {
540  // Done reading
541  str.assign(buf, nChar);
542  return *this;
543  }
544  }
545  else if (c == token::NL)
546  {
547  if (escaped)
548  {
549  escaped = false;
550  --nChar; // Overwrite backslash
551  }
552  else
553  {
554  buf[errLen] = buf[nChar] = '\0';
555 
557  << "found '\\n' while reading string \""
558  << buf << "...\""
559  << exit(FatalIOError);
560 
561  return *this;
562  }
563  }
564  else if (c == '\\')
565  {
566  escaped = !escaped; // toggle state (retains backslashes)
567  }
568  else
569  {
570  escaped = false;
571  }
572 
573  buf[nChar++] = c;
574  }
575 
576  if (nChar >= maxLen)
577  {
578  buf[errLen] = '\0';
579 
581  << "string \"" << buf << "...\"\n"
582  << " is too long (max. " << maxLen << " characters)"
583  << exit(FatalIOError);
584 
585  return *this;
586  }
587 
588  // Don't worry about a dangling backslash if string terminated prematurely
589  buf[errLen] = buf[nChar] = '\0';
590 
592  << "Problem while reading string \"" << buf << "...\""
593  << exit(FatalIOError);
594 
595  return *this;
596 }
597 
598 
599 Foam::Istream& Foam::ISstream::readVariable(std::string& str)
600 {
601  constexpr const unsigned maxLen = 1024;
602  static char buf[maxLen];
603 
604  unsigned nChar = 0;
605  unsigned depth = 0; // Track depth of (..) or {..} nesting
606  char c;
607 
608  // First character must be '$'
609  if (!get(c) || c != token::DOLLAR)
610  {
612  << "Invalid first character found : " << c << nl
613  << exit(FatalIOError);
614  }
615  buf[nChar++] = c;
616 
617  // Next character should also exist.
618  // This should never fail, since it was checked before calling.
619  if (!get(c))
620  {
621  str.assign(buf, nChar);
622 
623  IOWarningInFunction(*this)
624  << "Truncated variable name : " << str << nl;
625 
626  return *this;
627  }
628  buf[nChar++] = c;
629 
630  str.clear();
631  if (c == token::BEGIN_BLOCK)
632  {
633  // Processing ${...} style.
634  ++depth;
635 
636  // Could check that the next char is good and not one of '{}'
637  // since this would indicate "${}", "${{..." or truncated "${"
638 
639  while (get(c))
640  {
641  buf[nChar++] = c;
642  if (nChar == maxLen)
643  {
644  str.append(buf, nChar);
645  nChar = 0;
646  }
647  if (c == token::BEGIN_BLOCK)
648  {
649  ++depth;
650  }
651  else if (c == token::END_BLOCK)
652  {
653  --depth;
654  if (!depth)
655  {
656  // Found closing '}' character
657  str.append(buf, nChar);
658  return *this;
659  }
660  }
661  }
662 
663  // Should never reach here on normal input
664 
665  str.append(buf, nChar); // Finalize pending buffer input
666 
667  nChar = str.length();
668  if (str.length() > errLen)
669  {
670  str.erase(errLen);
671  }
672 
674  << "stream terminated while reading variable '"
675  << str.c_str() << "...' [" << nChar << "]\n"
676  << exit(FatalIOError);
677 
678  return *this;
679  }
680  else if (validVariableChar(c))
681  {
682  // Processing $var style
683 
684  while
685  (
686  (nChar < maxLen) && get(c)
687  && (validVariableChar(c))
688  )
689  {
690  if (c == token::BEGIN_LIST)
691  {
692  ++depth;
693  }
694  else if (c == token::END_LIST)
695  {
696  if (!depth)
697  {
698  break; // Closed ')' without an opening '(' ? ... stop
699  }
700  --depth;
701  }
702 
703  buf[nChar++] = c;
704  }
705  }
706  else
707  {
708  // Invalid character. Terminate string (for message) without
709  // including the invalid character in the count.
710 
711  buf[nChar--] = '\0';
712 
713  IOWarningInFunction(*this)
714  << "Bad variable name: " << buf << nl << endl;
715  }
716 
717  if (nChar >= maxLen)
718  {
719  buf[errLen] = '\0';
720 
722  << "variable '" << buf << "...'\n"
723  << " is too long (max. " << maxLen << " characters)"
724  << exit(FatalIOError);
725 
726  return *this;
727  }
728 
729  buf[nChar] = '\0'; // Terminate string
730 
731  if (bad())
732  {
733  // Could probably skip this check
734  buf[errLen] = '\0';
735 
737  << "Problem while reading variable '" << buf << "...' after "
738  << nChar << " characters\n"
739  << exit(FatalIOError);
740 
741  return *this;
742  }
743 
744  if (depth)
745  {
746  IOWarningInFunction(*this)
747  << "Missing " << depth
748  << " closing ')' while parsing" << nl << nl
749  << buf << nl << endl;
750  }
751 
752  // Finalize
753  str.assign(buf, nChar);
754  putback(c);
755 
756  return *this;
757 }
758 
759 
760 Foam::Istream& Foam::ISstream::readVerbatim(std::string& str)
761 {
762  constexpr const unsigned maxLen = 8000;
763  static char buf[maxLen];
764 
765  unsigned nChar = 0;
766  char c;
767 
768  str.clear();
769  while (get(c))
770  {
771  if (c == token::HASH)
772  {
773  char nextC;
774  get(nextC);
775  if (nextC == token::END_BLOCK)
776  {
777  // Found closing "#}" sequence
778  str.append(buf, nChar);
779  return *this;
780  }
781  else
782  {
783  putback(nextC);
784  }
785  }
786 
787  buf[nChar++] = c;
788  if (nChar == maxLen)
789  {
790  str.append(buf, nChar);
791  nChar = 0;
792  }
793  }
794 
795  // Truncated terminated prematurely
796  buf[errLen] = buf[nChar] = '\0';
797 
799  << "Problem while reading string \"" << buf << "...\""
800  << exit(FatalIOError);
801 
802  return *this;
803 }
804 
805 
807 {
808  is_ >> val;
809  setState(is_.rdstate());
810  return *this;
811 }
812 
813 
815 {
816  is_ >> val;
817  setState(is_.rdstate());
818  return *this;
819 }
820 
821 
823 {
824  is_ >> val;
825  setState(is_.rdstate());
826  return *this;
827 }
828 
829 
830 Foam::Istream& Foam::ISstream::read(char* buf, std::streamsize count)
831 {
832  beginRawRead();
833  readRaw(buf, count);
834  endRawRead();
835 
836  return *this;
837 }
838 
839 
840 Foam::Istream& Foam::ISstream::readRaw(char* buf, std::streamsize count)
841 {
842  is_.read(buf, count);
843  setState(is_.rdstate());
844 
845  return *this;
846 }
847 
848 
850 {
851  if (format() != BINARY)
852  {
854  << "stream format not binary"
855  << exit(FatalIOError);
856  }
857 
858  readBegin("binaryBlock");
859  setState(is_.rdstate());
860 
861  return is_.good();
862 }
863 
864 
866 {
867  readEnd("binaryBlock");
868  setState(is_.rdstate());
869 
870  return is_.good();
871 }
872 
873 
875 {
876  lineNumber_ = 1; // Reset line number
877 
878  stdStream().clear(); // Clear the iostate error state flags
879  setGood(); // Sync local copy of iostate
880 
881  // pubseekpos() rather than seekg() so that it works with gzstream
882  stdStream().rdbuf()->pubseekpos(0, std::ios_base::in);
883 }
884 
885 
886 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
887 
888 std::ios_base::fmtflags Foam::ISstream::flags() const
889 {
890  return is_.flags();
891 }
892 
893 
894 std::ios_base::fmtflags Foam::ISstream::flags(const ios_base::fmtflags f)
895 {
896  return is_.flags(f);
897 }
898 
899 
900 // ************************************************************************* //
Foam::token::SUBTRACT
Subtract or start of negative number.
Definition: token.H:138
Foam::token::ASSIGN
Assignment/equals [isseparator].
Definition: token.H:136
token.H
Foam::doubleScalar
double doubleScalar
A typedef for double.
Definition: scalarFwd.H:48
Foam::token::COMMA
Comma [isseparator].
Definition: token.H:129
int.H
System signed integer.
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::token::lineNumber
label lineNumber() const noexcept
The line number for the token.
Definition: tokenI.H:387
Foam::floatScalar
float floatScalar
A typedef for float.
Definition: scalarFwd.H:45
ISstream.H
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
Foam::token::END_STRING
End string with double quote.
Definition: token.H:143
Foam::FatalIOError
IOerror FatalIOError
Foam::charToWord
static Foam::word charToWord(char c)
Definition: UIPstream.C:41
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::token
A token holds an item read from Istream.
Definition: token.H:68
Foam::ISstream::rewind
virtual void rewind()
Rewind the stream so that it may be read again.
Definition: ISstream.C:874
Foam::ISstream::readRaw
virtual Istream & readRaw(char *data, std::streamsize count)
Low-level raw binary read.
Definition: ISstream.C:840
Foam::ISstream::get
ISstream & get(char &c)
Raw, low-level get character function.
Definition: ISstreamI.H:56
Foam::token::DIVIDE
Divide [isseparator].
Definition: token.H:140
format
word format(conversionProperties.get< word >("format"))
Foam::ISstream::endRawRead
virtual bool endRawRead()
End of low-level raw binary read.
Definition: ISstream.C:865
Foam::token::BEGIN_SQR
Begin dimensions [isseparator].
Definition: token.H:124
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::token::END_STATEMENT
End entry [isseparator].
Definition: token.H:121
Foam::token::compound::isCompound
static bool isCompound(const word &name)
Test if name is a known (registered) compound type.
Definition: token.C:80
Foam::token::END_BLOCK
End block [isseparator].
Definition: token.H:127
Foam::ISstream::putback
ISstream & putback(const char c)
Raw, low-level putback character function.
Definition: ISstreamI.H:106
Foam::token::DOLLAR
Dollar - start variable.
Definition: token.H:131
Foam::token::NL
Newline [isspace].
Definition: token.H:119
Foam::word::valid
static bool valid(char c)
Is this character valid for a word?
Definition: wordI.H:130
Foam::IOstream::bad
bool bad() const
Return true if stream is corrupted.
Definition: IOstream.H:242
Foam::token::END_SQR
End dimensions [isseparator].
Definition: token.H:125
Foam::token::HASH
Hash - directive or verbatim string.
Definition: token.H:130
Foam::token::MULTIPLY
Multiply [isseparator].
Definition: token.H:139
Foam::token::BEGIN_BLOCK
Begin block [isseparator].
Definition: token.H:126
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::Istream::getBack
bool getBack(token &tok)
Get the put back token if there is one and return true.
Definition: Istream.C:75
Foam::token::COLON
Colon [isseparator].
Definition: token.H:128
Foam::nl
constexpr char nl
Definition: Ostream.H:385
f
labelList f(nPoints)
Foam::BitOps::count
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition: BitOps.H:77
Foam::ISstream::flags
virtual ios_base::fmtflags flags() const
Return flags of output stream.
Definition: ISstream.C:888
Foam::ISstream::read
virtual Istream & read(token &t)
Return next token from stream.
Definition: ISstream.C:158
errLen
static constexpr const unsigned errLen
Definition: ISstream.C:37
Foam::token::END_LIST
End list [isseparator].
Definition: token.H:123
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
Foam::token::compound::New
static autoPtr< compound > New(const word &type, Istream &is)
Construct compound from Istream.
Definition: token.C:56
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:401
IOWarningInFunction
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
Definition: messageStream.H:315
Foam::IOstream::good
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:224
Foam::ISstream::beginRawRead
virtual bool beginRawRead()
Start of low-level raw binary read.
Definition: ISstream.C:849
Foam::token::BEGIN_LIST
Begin list [isseparator].
Definition: token.H:122
Foam::token::setType
bool setType(const tokenType tokType) noexcept
Change the token type, for similar types.
Definition: tokenI.H:315
Foam::isspace
bool isspace(char c)
Test for horizontal whitespace.
Definition: char.H:63
Foam::token::BEGIN_STRING
Begin string with double quote.
Definition: token.H:142
Foam::token::punctuationToken
punctuationToken
Standard punctuation tokens (a character)
Definition: token.H:114
Foam::token::ADD
Addition [isseparator].
Definition: token.H:137
Foam::Istream::read
virtual Istream & read(token &)=0
Return next token from stream.
Foam::token::setBad
void setBad()
Clear token and set to be ERROR.
Definition: tokenI.H:688