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-2019 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  }
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::VERBATIMSTRING);
251  }
252  }
253  else
254  {
255  // Word beginning with '#'. Eg, "#include"
256  putback(nextC);
257  putback(c);
258 
259  readWordToken(t);
260  }
261 
262  return *this;
263  }
264 
265  // Dictionary variable (as rvalue)
266  case token::DOLLAR :
267  {
268  char nextC;
269  if (read(nextC).bad())
270  {
271  // Return lone '$' as word
272  t = charToWord(c);
273  }
274  else
275  {
276  // Put back both so that '$...' is included in the variable
277  putback(nextC);
278  putback(c);
279 
280  string val;
281  if (readVariable(val).bad())
282  {
283  t.setBad();
284  }
285  else
286  {
287  t = std::move(val); // Move contents to token
288  t.setType(token::tokenType::VARIABLE);
289  }
290  }
291 
292  return *this;
293  }
294 
295  // Number: integer or floating point
296  //
297  // ideally match the equivalent of this regular expression
298  //
299  // /[-+]?([0-9]+\.?[0-9]*|\.[0-9]+)([Ee][-+]?[0-9]+)?/
300  //
301  case '-' :
302  case '.' :
303  case '0' : case '1' : case '2' : case '3' : case '4' :
304  case '5' : case '6' : case '7' : case '8' : case '9' :
305  {
306  label labelVal = (c != '.'); // used as bool here
307 
308  unsigned nChar = 0;
309  buf[nChar++] = c;
310 
311  // get everything that could resemble a number and let
312  // readScalar determine the validity
313  while
314  (
315  is_.get(c)
316  && (
317  isdigit(c)
318  || c == '+'
319  || c == '-'
320  || c == '.'
321  || c == 'E'
322  || c == 'e'
323  )
324  )
325  {
326  if (labelVal)
327  {
328  labelVal = isdigit(c);
329  }
330 
331  buf[nChar++] = c;
332  if (nChar == maxLen)
333  {
334  // Runaway argument - avoid buffer overflow
335  buf[maxLen-1] = '\0';
336 
338  << "number '" << buf << "...'\n"
339  << " is too long (max. " << maxLen << " characters)"
340  << exit(FatalIOError);
341 
342  t.setBad();
343  return *this;
344  }
345  }
346  buf[nChar] = '\0'; // Terminate string
347 
348  setState(is_.rdstate());
349  if (is_.bad())
350  {
351  t.setBad();
352  }
353  else
354  {
355  is_.putback(c);
356 
357  if (nChar == 1 && buf[0] == '-')
358  {
359  // A single '-' is punctuation
361  }
362  else if (labelVal && Foam::read(buf, labelVal))
363  {
364  t = labelVal;
365  }
366  else
367  {
368  scalar scalarVal;
369 
370  if (readScalar(buf, scalarVal))
371  {
372  // A scalar or too big to fit as a label
373  t = scalarVal;
374  }
375  else
376  {
377  t.setBad();
378  }
379  }
380  }
381 
382  return *this;
383  }
384 
385 
386  // Should be a word (which can also be a single character)
387  default:
388  {
389  putback(c);
390  readWordToken(t);
391 
392  return *this;
393  }
394  }
395 }
396 
397 
399 {
400  c = nextValid();
401  return *this;
402 }
403 
404 
406 {
407  constexpr const unsigned maxLen = 1024;
408  static char buf[maxLen];
409 
410  unsigned nChar = 0;
411  unsigned depth = 0; // Track depth of (..) nesting
412  char c;
413 
414  while
415  (
416  (nChar < maxLen)
417  && get(c)
418  && word::valid(c)
419  )
420  {
421  if (c == token::BEGIN_LIST)
422  {
423  ++depth;
424  }
425  else if (c == token::END_LIST)
426  {
427  if (!depth)
428  {
429  break; // Closed ')' without a '(' ? ... stop
430  }
431  --depth;
432  }
433 
434  buf[nChar++] = c;
435  }
436 
437  if (nChar >= maxLen)
438  {
439  buf[errLen] = '\0';
440 
442  << "word '" << buf << "...'\n"
443  << " is too long (max. " << maxLen << " characters)"
444  << exit(FatalIOError);
445 
446  return *this;
447  }
448 
449  buf[nChar] = '\0'; // Terminate string
450 
451  if (bad())
452  {
453  // Could probably skip this check
454  buf[errLen] = '\0';
455 
457  << "Problem while reading word '" << buf << "...' after "
458  << nChar << " characters\n"
459  << exit(FatalIOError);
460 
461  return *this;
462  }
463 
464  if (nChar == 0)
465  {
467  << "Invalid first character found : " << c
468  << exit(FatalIOError);
469  }
470  else if (depth)
471  {
472  IOWarningInFunction(*this)
473  << "Missing " << depth
474  << " closing ')' while parsing" << nl << nl
475  << buf << nl << endl;
476  }
477 
478  // Finalize: content already validated, assign without additional checks.
479  str.assign(buf, nChar);
480  putback(c);
481 
482  return *this;
483 }
484 
485 
487 {
488  constexpr const unsigned maxLen = 1024;
489  static char buf[maxLen];
490 
491  char c;
492 
493  if (!get(c))
494  {
496  << "cannot read start of string"
497  << exit(FatalIOError);
498 
499  return *this;
500  }
501 
502  // Note, we could also handle single-quoted strings here (if desired)
503  if (c != token::BEGIN_STRING)
504  {
506  << "Incorrect start of string character found : " << c
507  << exit(FatalIOError);
508 
509  return *this;
510  }
511 
512  unsigned nChar = 0;
513  bool escaped = false;
514 
515  while
516  (
517  (nChar < maxLen)
518  && get(c)
519  )
520  {
521  if (c == token::END_STRING)
522  {
523  if (escaped)
524  {
525  escaped = false;
526  --nChar; // Overwrite backslash
527  }
528  else
529  {
530  // Done reading
531  str.assign(buf, nChar);
532  return *this;
533  }
534  }
535  else if (c == token::NL)
536  {
537  if (escaped)
538  {
539  escaped = false;
540  --nChar; // Overwrite backslash
541  }
542  else
543  {
544  buf[errLen] = buf[nChar] = '\0';
545 
547  << "found '\\n' while reading string \""
548  << buf << "...\""
549  << exit(FatalIOError);
550 
551  return *this;
552  }
553  }
554  else if (c == '\\')
555  {
556  escaped = !escaped; // toggle state (retains backslashes)
557  }
558  else
559  {
560  escaped = false;
561  }
562 
563  buf[nChar++] = c;
564  }
565 
566  if (nChar >= maxLen)
567  {
568  buf[errLen] = '\0';
569 
571  << "string \"" << buf << "...\"\n"
572  << " is too long (max. " << maxLen << " characters)"
573  << exit(FatalIOError);
574 
575  return *this;
576  }
577 
578  // Don't worry about a dangling backslash if string terminated prematurely
579  buf[errLen] = buf[nChar] = '\0';
580 
582  << "Problem while reading string \"" << buf << "...\""
583  << exit(FatalIOError);
584 
585  return *this;
586 }
587 
588 
589 Foam::Istream& Foam::ISstream::readVariable(std::string& str)
590 {
591  constexpr const unsigned maxLen = 1024;
592  static char buf[maxLen];
593 
594  unsigned nChar = 0;
595  unsigned depth = 0; // Track depth of (..) or {..} nesting
596  char c;
597 
598  // First character must be '$'
599  if (!get(c) || c != token::DOLLAR)
600  {
602  << "Invalid first character found : " << c << nl
603  << exit(FatalIOError);
604  }
605  buf[nChar++] = c;
606 
607  // Next character should also exist.
608  // This should never fail, since it was checked before calling.
609  if (!get(c))
610  {
611  str.assign(buf, nChar);
612 
613  IOWarningInFunction(*this)
614  << "Truncated variable name : " << str << nl;
615 
616  return *this;
617  }
618  buf[nChar++] = c;
619 
620  char endChar = token::END_LIST;
621 
622  if (c == token::BEGIN_BLOCK)
623  {
624  // Processing ${...} style
625 
626  endChar = token::END_BLOCK;
627  ++depth;
628 
629  // Could check that the next char is good and not one of '{}'
630  // since this would indicate "${}", "${{..." or truncated "${"
631 
632  while
633  (
634  (nChar < maxLen) && get(c)
635  &&
636  (
637  validVariableChar(c)
638  || (c == token::BEGIN_BLOCK || c == token::END_BLOCK)
639  )
640  )
641  {
642  if (c == token::BEGIN_BLOCK)
643  {
644  ++depth;
645  }
646  else if (c == token::END_BLOCK)
647  {
648  if (!depth)
649  {
650  break; // Closed '}' without a '{' ? ... stop
651  }
652  --depth;
653  }
654 
655  buf[nChar++] = c;
656  }
657  }
658  else if (validVariableChar(c))
659  {
660  // Processing $var style
661 
662  while
663  (
664  (nChar < maxLen) && get(c)
665  && (validVariableChar(c))
666  )
667  {
668  if (c == token::BEGIN_LIST)
669  {
670  ++depth;
671  }
672  else if (c == token::END_LIST)
673  {
674  if (!depth)
675  {
676  break; // Closed ')' without a '(' ? ... stop
677  }
678  --depth;
679  }
680 
681  buf[nChar++] = c;
682  }
683  }
684  else
685  {
686  // Invalid character. Terminate string (for message) without
687  // including the invalid character in the count.
688 
689  buf[nChar--] = '\0';
690 
691  IOWarningInFunction(*this)
692  << "Bad variable name: " << buf << nl << endl;
693  }
694 
695  if (nChar >= maxLen)
696  {
697  buf[errLen] = '\0';
698 
700  << "variable '" << buf << "...'\n"
701  << " is too long (max. " << maxLen << " characters)"
702  << exit(FatalIOError);
703 
704  return *this;
705  }
706 
707  buf[nChar] = '\0'; // Terminate string
708 
709  if (bad())
710  {
711  // Could probably skip this check
712  buf[errLen] = '\0';
713 
715  << "Problem while reading variable '" << buf << "...' after "
716  << nChar << " characters\n"
717  << exit(FatalIOError);
718 
719  return *this;
720  }
721 
722  if (depth)
723  {
724  IOWarningInFunction(*this)
725  << "Missing " << depth
726  << " closing '" << endChar << "' while parsing" << nl << nl
727  << buf << nl << endl;
728  }
729 
730  // Finalize
731  str.assign(buf, nChar);
732  putback(c);
733 
734  return *this;
735 }
736 
737 
738 Foam::Istream& Foam::ISstream::readVerbatim(std::string& str)
739 {
740  constexpr const unsigned maxLen = 8000;
741  static char buf[maxLen];
742 
743  unsigned nChar = 0;
744  char c;
745 
746  str.clear();
747  while (get(c))
748  {
749  if (c == token::HASH)
750  {
751  char nextC;
752  get(nextC);
753  if (nextC == token::END_BLOCK)
754  {
755  // The closing "#}" found
756  str.append(buf, nChar);
757  return *this;
758  }
759  else
760  {
761  putback(nextC);
762  }
763  }
764 
765  buf[nChar++] = c;
766  if (nChar == maxLen)
767  {
768  str.append(buf, nChar);
769  nChar = 0;
770  }
771  }
772 
773  // Truncated terminated prematurely
774  buf[errLen] = buf[nChar] = '\0';
775 
777  << "Problem while reading string \"" << buf << "...\""
778  << exit(FatalIOError);
779 
780  return *this;
781 }
782 
783 
785 {
786  is_ >> val;
787  setState(is_.rdstate());
788  return *this;
789 }
790 
791 
793 {
794  is_ >> val;
795  setState(is_.rdstate());
796  return *this;
797 }
798 
799 
801 {
802  is_ >> val;
803  setState(is_.rdstate());
804  return *this;
805 }
806 
807 
808 Foam::Istream& Foam::ISstream::read(char* buf, std::streamsize count)
809 {
810  beginRawRead();
811  readRaw(buf, count);
812  endRawRead();
813 
814  return *this;
815 }
816 
817 
818 Foam::Istream& Foam::ISstream::readRaw(char* buf, std::streamsize count)
819 {
820  is_.read(buf, count);
821  setState(is_.rdstate());
822 
823  return *this;
824 }
825 
826 
828 {
829  if (format() != BINARY)
830  {
832  << "stream format not binary"
833  << exit(FatalIOError);
834  }
835 
836  readBegin("binaryBlock");
837  setState(is_.rdstate());
838 
839  return is_.good();
840 }
841 
842 
844 {
845  readEnd("binaryBlock");
846  setState(is_.rdstate());
847 
848  return is_.good();
849 }
850 
851 
853 {
854  lineNumber_ = 1; // Reset line number
855 
856  stdStream().clear(); // Clear the iostate error state flags
857  setGood(); // Sync local copy of iostate
858 
859  // pubseekpos() rather than seekg() so that it works with gzstream
860  stdStream().rdbuf()->pubseekpos(0, std::ios_base::in);
861 }
862 
863 
864 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
865 
866 std::ios_base::fmtflags Foam::ISstream::flags() const
867 {
868  return is_.flags();
869 }
870 
871 
872 std::ios_base::fmtflags Foam::ISstream::flags(const ios_base::fmtflags f)
873 {
874  return is_.flags(f);
875 }
876 
877 
878 // ************************************************************************* //
Foam::token::SUBTRACT
Subtract or start of negative number.
Definition: token.H:133
Foam::token::ASSIGN
Assignment/equals [isseparator].
Definition: token.H:131
token.H
Foam::val
label ListType::const_reference val
Definition: ListOps.H:407
Foam::doubleScalar
double doubleScalar
Floating-point double precision scalar type.
Definition: doubleScalar.H:52
Foam::token::COMMA
Comma [isseparator].
Definition: token.H:124
int.H
System signed integer.
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::floatScalar
float floatScalar
Floating-point single precision scalar type.
Definition: floatScalar.H:52
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:138
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:337
Foam::token
A token holds an item read from Istream.
Definition: token.H:69
Foam::ISstream::rewind
virtual void rewind()
Rewind the stream so that it may be read again.
Definition: ISstream.C:852
Foam::ISstream::readRaw
virtual Istream & readRaw(char *data, std::streamsize count)
Low-level raw binary read.
Definition: ISstream.C:818
Foam::ISstream::get
ISstream & get(char &c)
Raw, low-level get character function.
Definition: ISstreamI.H:58
Foam::token::DIVIDE
Divide [isseparator].
Definition: token.H:135
format
word format(conversionProperties.get< word >("format"))
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::ISstream::endRawRead
virtual bool endRawRead()
End of low-level raw binary read.
Definition: ISstream.C:843
Foam::token::BEGIN_SQR
Begin dimensions [isseparator].
Definition: token.H:119
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:116
Foam::token::compound::isCompound
static bool isCompound(const word &name)
Return true if name is a known (registered) compound type.
Definition: token.C:80
Foam::token::END_BLOCK
End block [isseparator].
Definition: token.H:122
Foam::ISstream::putback
ISstream & putback(const char c)
Raw, low-level putback character function.
Definition: ISstreamI.H:92
Foam::token::DOLLAR
Dollar - start variable.
Definition: token.H:126
Foam::token::NL
Newline [isspace].
Definition: token.H:114
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:234
Foam::token::END_SQR
End dimensions [isseparator].
Definition: token.H:120
Foam::token::HASH
Hash - directive or verbatim string.
Definition: token.H:125
Foam::token::setType
bool setType(const tokenType variant)
Change the token type, for similar types.
Definition: tokenI.H:301
Foam::token::MULTIPLY
Multiply [isseparator].
Definition: token.H:134
Foam::token::BEGIN_BLOCK
Begin block [isseparator].
Definition: token.H:121
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:123
Foam::nl
constexpr char nl
Definition: Ostream.H:372
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:74
Foam::ISstream::flags
virtual ios_base::fmtflags flags() const
Return flags of output stream.
Definition: ISstream.C:866
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:118
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)
Select null constructed.
Definition: token.C:56
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:375
IOWarningInFunction
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
Definition: messageStream.H:306
Foam::token::lineNumber
label lineNumber() const
The line number for the token.
Definition: tokenI.H:356
Foam::IOstream::good
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:216
Foam::ISstream::beginRawRead
virtual bool beginRawRead()
Start of low-level raw binary read.
Definition: ISstream.C:827
Foam::token::BEGIN_LIST
Begin list [isseparator].
Definition: token.H:117
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:137
Foam::token::punctuationToken
punctuationToken
Standard punctuation tokens (a character)
Definition: token.H:109
Foam::token::ADD
Addition [isseparator].
Definition: token.H:132
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:639