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-2021 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 #include <cstring>
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 // Truncate error message for readability
38 static constexpr const unsigned errLen = 80;
39 
40 
41 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
42 
43 namespace
44 {
45 
46 // Convert a single character to a word with length 1
47 inline Foam::word charToWord(char c)
48 {
49  return Foam::word(std::string(1, c), false);
50 }
51 
52 
53 // Permit slash-scoping of entries
54 inline bool validVariableChar(char c)
55 {
56  return (Foam::word::valid(c) || c == '/');
57 }
58 
59 
60 inline void inplaceTrimRight(std::string& s)
61 {
62  auto end = s.length();
63  if (end)
64  {
65  while (end && Foam::isspace(s[end-1]))
66  {
67  --end;
68  }
69 
70  s.erase(end);
71  }
72 }
73 
74 } // End anonymous namespace
75 
76 
77 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
78 
80 {
81  // Search for end of C-style comment - "*/"
82 
83  // Can use getLine(nullptr, '*') in the logic,
84  // but written out looks less obscure
85 
86  char c = 0;
87  bool star = false;
88 
89  while (get(c))
90  {
91  if (c == '*')
92  {
93  star = true;
94  }
95  else if (star)
96  {
97  star = false;
98  if (c == '/')
99  {
100  // Matched "*/"
101  return true;
102  }
103  }
104  }
105 
106  // Exhausted stream without finding "*/" sequence
107  return false;
108 }
109 
110 
111 char Foam::ISstream::nextValid()
112 {
113  char c = 0;
114 
115  // Get next non-whitespace character
116  while (get(c))
117  {
118  if (isspace(c))
119  {
120  continue;
121  }
122 
123  // Check if this starts a C/C++ comment
124  if (c == '/')
125  {
126  if (!get(c))
127  {
128  // Cannot get another character - return this one
129  return '/';
130  }
131 
132  if (c == '/')
133  {
134  // C++ comment: discard through newline
135  (void) getLine(nullptr, '\n');
136  }
137  else if (c == '*')
138  {
139  // C-style comment: discard through to "*/" ending
140  if (!seekCommentEnd_Cstyle())
141  {
142  return 0; // Premature end of stream
143  }
144  }
145  else
146  {
147  // The '/' did not start a C/C++ comment - return it
148  putback(c);
149  return '/';
150  }
151  }
152  else
153  {
154  // A valid character - return it
155  return c;
156  }
157  }
158 
159  return 0;
160 }
161 
162 
163 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
164 
165 namespace Foam
166 {
167 
168 // Read a verbatim string (excluding block delimiters),
169 // continuing until a closing "#}" has been found.
170 //
171 // The leading "#{" removed from stream prior to calling.
172 static ISstream& readVerbatim
173 (
174  ISstream& is,
175  std::string& str
176 )
177 {
178  constexpr const unsigned bufLen = 8000;
179  static char buf[bufLen];
180 
181  unsigned nChar = 0;
182  char c;
183 
184  str.clear();
185  while (is.get(c))
186  {
187  if (c == token::HASH)
188  {
189  char nextC;
190  is.get(nextC);
191  if (nextC == token::END_BLOCK)
192  {
193  // Found closing "#}" sequence
194  str.append(buf, nChar);
195  return is;
196  }
197  else
198  {
199  // Re-analyze the character
200  is.putback(nextC);
201  }
202  }
203 
204  buf[nChar++] = c;
205  if (nChar == bufLen) // Flush full buffer
206  {
207  str.append(buf, nChar);
208  nChar = 0;
209  }
210  }
211 
212 
213  // Abnormal exit of the loop
214  str.append(buf, nChar); // Finalize pending content
215  strncpy(buf, str.c_str(), errLen);
216  buf[errLen] = '\0';
217 
219  << "Problem while reading verbatim \"" << buf
220  << "...\" [after " << str.length() << " chars]\n"
221  << exit(FatalIOError);
222 
223  return is;
224 }
225 
226 
227 // Read a variable or expression.
228 // Handles "$var" and "${var}" forms, permits '/' scoping character.
229 // Also handles "${{expr}}".
230 //
231 // Return the token type or ERROR
232 //
233 // The leading "${" or "$c" removed from stream prior to calling.
235 (
236  ISstream& is,
237  std::string& str,
238  char c // Next character after '$'
239 )
240 {
241  constexpr const unsigned bufLen = 1024;
242  static char buf[bufLen];
243 
244  token::tokenType tokType(token::tokenType::VARIABLE);
245 
246  // The first two characters are known:
247  buf[0] = token::DOLLAR;
248  buf[1] = c;
249 
250  unsigned nChar = 2; // Starts with two characters
251  unsigned depth = 0; // Depth of {..} nesting
252 
253  str.clear();
254  if (c == token::BEGIN_BLOCK)
255  {
256  // Processing '${variable}' or '${{expr}}'
257  ++depth;
258 
259  int lookahead = is.peek();
260  if (lookahead == token::BEGIN_BLOCK)
261  {
262  // Looks like '${{expr...'
263  tokType = token::tokenType::EXPRESSION;
264  }
265  else if (lookahead == token::END_BLOCK)
266  {
267  // Looks like '${}'
269  << "Ignoring empty ${}" << endl;
270  return token::tokenType::ERROR;
271  }
272 
273  while (is.get(c))
274  {
275  buf[nChar++] = c;
276 
277  if (c == token::BEGIN_BLOCK)
278  {
279  ++depth;
280  }
281  else if (c == token::END_BLOCK)
282  {
283  --depth;
284  if (!depth)
285  {
286  // Found closing '}' character
287  str.append(buf, nChar);
288  return tokType;
289  }
290  }
291  else if (c == '/' && tokType == token::tokenType::EXPRESSION)
292  {
293  // Strip C/C++ comments from expressions
294  // Note: could also peek instead of get/putback
295 
296  if (!is.get(c))
297  {
298  break; // Premature end of stream
299  }
300  else if (c == '/')
301  {
302  --nChar; // Remove initial '/' from buffer
303 
304  // C++ comment: discard through newline
305  (void) is.getLine(nullptr, '\n');
306  }
307  else if (c == '*')
308  {
309  --nChar; // Remove initial '/' from buffer
310 
311  // C-style comment: seek "*/" ending
312  if (!is.seekCommentEnd_Cstyle())
313  {
314  break; // Premature end of stream
315  }
316  }
317  else
318  {
319  // Re-analyze the character
320  is.putback(c);
321  }
322  }
323 
324  if (nChar == bufLen) // Flush full buffer
325  {
326  str.append(buf, nChar);
327  nChar = 0;
328  }
329  }
330 
331 
332  // Abnormal exit of the loop
333 
334  str.append(buf, nChar); // Finalize pending content
335  strncpy(buf, str.c_str(), errLen);
336  buf[errLen] = '\0';
337 
339  << "stream terminated while reading variable '" << buf
340  << "...' [after " << str.length() << " chars]\n"
341  << exit(FatalIOError);
342 
343  return token::tokenType::ERROR;
344  }
345  else if (validVariableChar(c))
346  {
347  // Processing '$variable'
348 
349  while (is.get(c))
350  {
351  if (!validVariableChar(c))
352  {
353  is.putback(c);
354  break;
355  }
356 
357  if (c == token::BEGIN_LIST)
358  {
359  ++depth;
360  }
361  else if (c == token::END_LIST)
362  {
363  if (!depth)
364  {
365  // Closed ')' without opening '(':
366  // - don't consider it part of our input
367  is.putback(c);
368  break;
369  }
370  --depth;
371  }
372 
373  buf[nChar++] = c;
374  if (nChar == bufLen) // Flush full buffer
375  {
376  str.append(buf, nChar);
377  nChar = 0;
378  }
379  }
380 
381  str.append(buf, nChar); // Finalize pending content
382 
383  if (depth)
384  {
385  strncpy(buf, str.c_str(), errLen);
386  buf[errLen] = '\0';
387 
389  << "Missing " << depth
390  << " closing ')' while parsing" << nl << nl
391  << buf << endl;
392  }
393 
394  return tokType;
395  }
396  else
397  {
398  // Invalid character. Terminate string (for message)
399 
400  buf[nChar--] = '\0';
401 
403  << "Ignoring bad variable name: " << buf << nl << endl;
404  }
405 
406  return token::tokenType::ERROR;
407 }
408 
409 
410 // Raw, low-level get into a string.
411 // Continues reading after an initial opening delimiter (eg, '{')
412 // until it finds the matching closing delimiter (eg, '}')
413 static bool readUntilBalancedDelimiter
414 (
415  ISstream& is,
416  std::string& str,
417  const bool stripComments,
418  const char delimOpen,
419  const char delimClose
420 )
421 {
422  constexpr const unsigned bufLen = 1024;
423  static char buf[bufLen];
424 
425  unsigned nChar = 0;
426  unsigned depth = 1; // Initial '{' already seen by caller
427  char c = 0;
428 
429  str.clear();
430  while (is.get(c))
431  {
432  if ((str.empty() && !nChar) && isspace(c))
433  {
434  continue; // Ignore leading whitespace
435  }
436 
437  buf[nChar++] = c;
438 
439  // Note: no '\' escape handling needed at the moment
440 
441  if (c == delimOpen)
442  {
443  ++depth;
444  }
445  else if (c == delimClose)
446  {
447  --depth;
448  if (!depth)
449  {
450  // Closing character - do not include in output
451  --nChar;
452  str.append(buf, nChar);
453  inplaceTrimRight(str); // Remove trailing whitespace
454  return true;
455  }
456  }
457  else if (stripComments && c == '/')
458  {
459  // Strip C/C++ comments from expressions
460  // Note: could also peek instead of get/putback
461 
462  if (!is.get(c))
463  {
464  break; // Premature end of stream
465  }
466  else if (c == '/')
467  {
468  --nChar; // Remove initial '/' from buffer
469 
470  // C++ comment: discard through newline
471  (void) is.getLine(nullptr, '\n');
472  }
473  else if (c == '*')
474  {
475  --nChar; // Remove initial '/' from buffer
476 
477  // C-style comment: discard through to "*/" ending
478  if (!is.seekCommentEnd_Cstyle())
479  {
480  break; // Premature end of stream
481  }
482  }
483  else
484  {
485  // Reanalyze the char
486  is.putback(c);
487  }
488  }
489 
490  if (nChar == bufLen)
491  {
492  str.append(buf, nChar); // Flush full buffer
493  nChar = 0;
494  }
495  }
496 
497 
498  // Abnormal exit of the loop
499 
500  str.append(buf, nChar); // Finalize pending content
501  inplaceTrimRight(str); // Remove trailing whitespace
502 
503  // Exhausted stream without finding closing sequence
504  return false;
505 }
506 
507 } // End namespace Foam
508 
509 
510 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
511 
513 (
514  std::string& str,
515  const bool stripComments
516 )
517 {
518  return
520  (
521  *this,
522  str,
523  stripComments,
526  );
527 }
528 
529 
531 {
532  constexpr const unsigned bufLen = 128; // Max length for labels/scalars
533  static char buf[bufLen];
534 
535  // Return the putback token if it exists
536  if (Istream::getBack(t))
537  {
538  return *this;
539  }
540 
541  // Assume that the streams supplied are in working order.
542  // Lines are counted by '\n'
543 
544  // Get next 'valid character': i.e. proceed through any whitespace
545  // and/or comments until a semantically valid character is found
546 
547  char c = nextValid();
548 
549  // Set the line number of this token to the current stream line number
550  t.lineNumber(this->lineNumber());
551 
552  // Return on error
553  if (!c)
554  {
555  t.setBad();
556  return *this;
557  }
558 
559  // Analyse input starting with this character.
560  switch (c)
561  {
562  // Check for punctuation first - same as token::isseparator()
563 
564  case token::END_STATEMENT :
565  case token::BEGIN_LIST :
566  case token::END_LIST :
567  case token::BEGIN_SQR :
568  case token::END_SQR :
569  case token::BEGIN_BLOCK :
570  case token::END_BLOCK :
571  case token::COLON :
572  case token::COMMA :
573  case token::ASSIGN :
574  case token::PLUS :
575  // NB: token::MINUS handled later as the possible start of a Number
576  case token::MULTIPLY :
577  case token::DIVIDE :
578  {
580  return *this;
581  }
582 
583  // String: enclosed by double quotes.
584  case token::DQUOTE :
585  {
586  putback(c);
587 
588  string val;
589  if (read(val).bad())
590  {
591  t.setBad();
592  }
593  else
594  {
595  t = std::move(val); // Move contents to token
596  }
597 
598  return *this;
599  }
600 
601  // Verbatim string '#{ .. #}' or dictionary '#directive'
602  case token::HASH :
603  {
604  char nextC;
605  int lookahead = peek();
606 
607  if (lookahead == token::BEGIN_BLOCK)
608  {
609  // Verbatim string: #{ ... #}
610  // Token stored without the surrounding delimiters
611 
612  (void) get(nextC); // Discard '{' lookahead
613 
614  string val;
615  if (readVerbatim(*this, val).bad())
616  {
617  t.setBad();
618  }
619  else
620  {
621  t = std::move(val); // Move contents to token
622  t.setType(token::tokenType::VERBATIM);
623  }
624  }
625  else if (read(nextC).bad())
626  {
627  // Return lone '#' as word
628  t = charToWord(c);
629  }
630  else if (word::valid(nextC))
631  {
632  // Directive (wordToken) beginning with '#'. Eg, "#include"
633  // Put back both so that '#...' is included in the directive
634 
635  putback(nextC);
636  putback(c);
637 
638  word val;
639  if (read(val).bad())
640  {
641  t.setBad();
642  }
643  else
644  {
645  t = std::move(val); // Move contents to token
646  t.setType(token::tokenType::DIRECTIVE);
647  }
648  }
649  else
650  {
651  // '#' followed by non-word. Just ignore leading '#'?
652  putback(nextC);
653 
654  IOWarningInFunction(*this)
655  << "Invalid sequence #" << char(nextC)
656  << " ... ignoring the leading '#'" << nl << endl;
657  }
658 
659  return *this;
660  }
661 
662  // Dictionary variable or ${{ expression }}
663  case token::DOLLAR :
664  {
665  char nextC;
666  if (read(nextC).bad())
667  {
668  // Return lone '$' as word. Could also ignore
669  t = charToWord(c);
670  }
671  else
672  {
673  // NB: the parser is slightly generous here.
674  // It will also accept '$ {' as input.
675  // - to be revisited (2021-05-17)
676 
677  string val;
678  token::tokenType tokType = readVariable(*this, val, nextC);
679  if (tokType == token::tokenType::ERROR)
680  {
681  t.setBad();
682  }
683  else
684  {
685  t = std::move(val); // Move contents to token
686  t.setType(tokType);
687  }
688  }
689 
690  return *this;
691  }
692 
693  // Number: integer or floating point
694  //
695  // ideally match the equivalent of this regular expression
696  //
697  // /[-+]?([0-9]+\.?[0-9]*|\.[0-9]+)([Ee][-+]?[0-9]+)?/
698  //
699  case '-' :
700  case '.' :
701  case '0' : case '1' : case '2' : case '3' : case '4' :
702  case '5' : case '6' : case '7' : case '8' : case '9' :
703  {
704  label labelVal = (c != '.'); // used as bool here
705 
706  unsigned nChar = 0;
707  buf[nChar++] = c;
708 
709  // get everything that could resemble a number and let
710  // readScalar determine the validity
711  while
712  (
713  is_.get(c)
714  && (
715  isdigit(c)
716  || c == '+'
717  || c == '-'
718  || c == '.'
719  || c == 'E'
720  || c == 'e'
721  )
722  )
723  {
724  if (labelVal)
725  {
726  labelVal = isdigit(c);
727  }
728 
729  buf[nChar++] = c;
730  if (nChar == bufLen)
731  {
732  // Runaway argument - avoid buffer overflow
733  buf[bufLen-1] = '\0';
734 
736  << "Number '" << buf << "...'\n"
737  << " is too long (max. " << bufLen << " characters)"
738  << exit(FatalIOError);
739 
740  t.setBad();
741  return *this;
742  }
743  }
744  buf[nChar] = '\0'; // Terminate string
745 
746  setState(is_.rdstate());
747  if (is_.bad())
748  {
749  t.setBad();
750  }
751  else
752  {
753  is_.putback(c);
754 
755  if (nChar == 1 && buf[0] == '-')
756  {
757  // A single '-' is punctuation
759  }
760  else if (labelVal && Foam::read(buf, labelVal))
761  {
762  t = labelVal;
763  }
764  else
765  {
766  scalar scalarVal;
767 
768  if (readScalar(buf, scalarVal))
769  {
770  // A scalar or too big to fit as a label
771  t = scalarVal;
772  }
773  else
774  {
775  t.setBad();
776  }
777  }
778  }
779 
780  return *this;
781  }
782 
783  // Should be a word (which can also be a single character)
784  default:
785  {
786  putback(c);
787 
788  word val;
789  if (read(val).bad())
790  {
791  t.setBad();
792  }
793  else if (token::compound::isCompound(val))
794  {
795  t = token::compound::New(val, *this).ptr();
796  }
797  else
798  {
799  t = std::move(val); // Move contents to token
800  }
801 
802  return *this;
803  }
804  }
805 }
806 
807 
809 {
810  c = nextValid();
811  return *this;
812 }
813 
814 
816 {
817  constexpr const unsigned bufLen = 1024;
818  static char buf[bufLen];
819 
820  unsigned nChar = 0;
821  unsigned depth = 0; // Depth of (..) nesting
822  char c;
823 
824  str.clear();
825  while (get(c))
826  {
827  if (!word::valid(c))
828  {
829  putback(c);
830  break;
831  }
832 
833  if (c == token::BEGIN_LIST)
834  {
835  ++depth;
836  }
837  else if (c == token::END_LIST)
838  {
839  if (!depth)
840  {
841  // Closed ')' without opening '(':
842  // - don't consider it part of our input
843  putback(c);
844  break;
845  }
846  --depth;
847  }
848 
849  buf[nChar++] = c;
850  if (nChar == bufLen) // Flush full buffer
851  {
852  str.append(buf, nChar);
853  nChar = 0;
854  }
855  }
856 
857  str.append(buf, nChar); // Finalize pending content
858 
859  if (bad())
860  {
861  // Could probably skip this check
862 
863  strncpy(buf, str.c_str(), errLen);
864  buf[errLen] = '\0';
865 
867  << "Problem while reading word '" << buf
868  << "...' [after " << str.length() << " chars]\n"
869  << exit(FatalIOError);
870 
871  return *this;
872  }
873 
874  if (str.empty())
875  {
877  << "Invalid first character found : " << c
878  << exit(FatalIOError);
879  }
880  else if (depth)
881  {
882  strncpy(buf, str.c_str(), errLen);
883  buf[errLen] = '\0';
884 
885  IOWarningInFunction(*this)
886  << "Missing " << depth
887  << " closing ')' while parsing" << nl << nl
888  << buf << nl << endl;
889  }
890 
891  return *this;
892 }
893 
894 
896 {
897  constexpr const unsigned bufLen = 1024;
898  static char buf[bufLen];
899 
900  unsigned nChar = 0;
901  char c;
902 
903  if (!get(c))
904  {
906  << "cannot read start of string"
907  << exit(FatalIOError);
908 
909  return *this;
910  }
911 
912  // Note, we could also handle single-quoted strings here (if desired)
913  if (c != token::DQUOTE)
914  {
916  << "Incorrect start of string character found : " << c
917  << exit(FatalIOError);
918 
919  return *this;
920  }
921 
922  str.clear();
923  bool escaped = false;
924  while (get(c))
925  {
926  if (c == '\\')
927  {
928  escaped = !escaped; // Toggle state (retains backslashes)
929  }
930  else if (c == token::DQUOTE)
931  {
932  if (escaped)
933  {
934  escaped = false;
935  --nChar; // Overwrite backslash
936  }
937  else
938  {
939  // Done reading
940  str.append(buf, nChar);
941  return *this;
942  }
943  }
944  else if (c == token::NL)
945  {
946  if (escaped)
947  {
948  escaped = false;
949  --nChar; // Overwrite backslash
950  }
951  else
952  {
953  str.append(buf, nChar); // Finalize pending content
954  strncpy(buf, str.c_str(), errLen);
955  buf[errLen] = '\0';
956 
958  << "Unescaped '\\n' while reading string \"" << buf
959  << "...\" [after " << str.length() << " chars]\n"
960  << exit(FatalIOError);
961 
962  return *this;
963  }
964  }
965  else
966  {
967  escaped = false;
968  }
969 
970  buf[nChar++] = c;
971  if (nChar == bufLen) // Flush full buffer
972  {
973  // Keep lookback character (eg, for backslash escaping)
974  str.append(buf, nChar-1);
975  nChar = 1;
976  buf[0] = c;
977  }
978  }
979 
980 
981  // Abnormal exit of the loop
982  // Don't worry about a dangling backslash if string terminated prematurely
983 
984  str.append(buf, nChar); // Finalize pending content
985  strncpy(buf, str.c_str(), errLen);
986  buf[errLen] = '\0';
987 
989  << "Problem while reading string \"" << buf << "...\""
990  << exit(FatalIOError);
991 
992  return *this;
993 }
994 
995 
997 {
998  is_ >> val;
999  setState(is_.rdstate());
1000  return *this;
1001 }
1002 
1003 
1005 {
1006  is_ >> val;
1007  setState(is_.rdstate());
1008  return *this;
1009 }
1010 
1011 
1013 {
1014  is_ >> val;
1015  setState(is_.rdstate());
1016  return *this;
1017 }
1018 
1019 
1020 Foam::Istream& Foam::ISstream::read(char* buf, std::streamsize count)
1021 {
1022  beginRawRead();
1023  readRaw(buf, count);
1024  endRawRead();
1025 
1026  return *this;
1027 }
1028 
1029 
1030 Foam::Istream& Foam::ISstream::readRaw(char* buf, std::streamsize count)
1031 {
1032  is_.read(buf, count);
1033  setState(is_.rdstate());
1034 
1035  return *this;
1036 }
1037 
1038 
1040 {
1041  if (format() != BINARY)
1042  {
1043  FatalIOErrorInFunction(*this)
1044  << "stream format not binary"
1045  << exit(FatalIOError);
1046  }
1047 
1048  readBegin("binaryBlock");
1049  setState(is_.rdstate());
1050 
1051  return is_.good();
1052 }
1053 
1054 
1056 {
1057  readEnd("binaryBlock");
1058  setState(is_.rdstate());
1059 
1060  return is_.good();
1061 }
1062 
1063 
1065 {
1066  lineNumber_ = 1; // Reset line number
1067 
1068  stdStream().clear(); // Clear the iostate error state flags
1069  setGood(); // Sync local copy of iostate
1070 
1071  // pubseekpos() rather than seekg() so that it works with gzstream
1072  stdStream().rdbuf()->pubseekpos(0, std::ios_base::in);
1073 }
1074 
1075 
1076 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1077 
1078 std::ios_base::fmtflags Foam::ISstream::flags() const
1079 {
1080  return is_.flags();
1081 }
1082 
1083 
1084 std::ios_base::fmtflags Foam::ISstream::flags(const ios_base::fmtflags f)
1085 {
1086  return is_.flags(f);
1087 }
1088 
1089 
1090 // ************************************************************************* //
Foam::token::ASSIGN
Assignment/equals [isseparator].
Definition: token.H:137
token.H
Foam::ISstream::peek
int peek()
Raw, low-level peek function.
Definition: ISstreamI.H:70
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::stringOps::inplaceTrimRight
void inplaceTrimRight(std::string &s)
Trim trailing whitespace inplace.
Definition: stringOps.C:992
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::ISstream::getLine
ISstream & getLine(std::string &str, char delim='\n')
Raw, low-level getline (until delimiter) into a string.
Definition: ISstreamI.H:76
s
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Definition: gmvOutputSpray.H:25
Foam::isspace
bool isspace(char c) noexcept
Test for whitespace (C-locale)
Definition: char.H:65
Foam::token::lineNumber
label lineNumber() const noexcept
The line number for the token.
Definition: tokenI.H:391
Foam::token::PLUS
Addition [isseparator].
Definition: token.H:138
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::ISstream
Generic input stream using a standard (STL) stream.
Definition: ISstream.H:55
Foam::readVerbatim
static ISstream & readVerbatim(ISstream &is, std::string &str)
Definition: ISstream.C:173
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:369
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:1064
Foam::ISstream::readRaw
virtual Istream & readRaw(char *data, std::streamsize count)
Low-level raw binary read.
Definition: ISstream.C:1030
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:141
Foam::token::MINUS
Subtract or start of negative number.
Definition: token.H:139
format
word format(conversionProperties.get< word >("format"))
Foam::token::DQUOTE
Double quote.
Definition: token.H:135
Foam::ISstream::endRawRead
virtual bool endRawRead()
End of low-level raw binary read.
Definition: ISstream.C:1055
Foam::readVariable
static token::tokenType readVariable(ISstream &is, std::string &str, char c)
Definition: ISstream.C:235
Foam::token::BEGIN_SQR
Begin dimensions [isseparator].
Definition: token.H:157
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::ISstream::seekCommentEnd_Cstyle
bool seekCommentEnd_Cstyle()
Discard until end of C-style comment '*‍/'.
Definition: ISstream.C:79
Foam::token::END_STATEMENT
End entry [isseparator].
Definition: token.H:154
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:160
Foam::ISstream::putback
ISstream & putback(const char c)
Raw, low-level putback character function.
Definition: ISstreamI.H:106
Foam::token::DOLLAR
Dollar - start variable or expression.
Definition: token.H:131
Foam::token::NL
Newline [isspace].
Definition: token.H:124
Foam::word::valid
static bool valid(char c)
Is this character valid for a word?
Definition: wordI.H:59
Foam::token::END_SQR
End dimensions [isseparator].
Definition: token.H:158
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:121
Foam::token::HASH
Hash - directive or start verbatim string.
Definition: token.H:130
Foam::IOstream::bad
bool bad() const noexcept
True if stream is corrupted.
Definition: IOstream.H:251
Foam::token::MULTIPLY
Multiply [isseparator].
Definition: token.H:140
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::token::BEGIN_BLOCK
Begin block [isseparator].
Definition: token.H:159
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::ISstream::continueReadUntilRightBrace
bool continueReadUntilRightBrace(std::string &str, const bool stripComments=true)
Definition: ISstream.C:513
Foam::Istream::getBack
bool getBack(token &tok)
Get the put-back token if there is one.
Definition: Istream.C:92
Foam::token::COLON
Colon [isseparator].
Definition: token.H:127
Foam::nl
constexpr char nl
Definition: Ostream.H:404
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::token::tokenType
tokenType
Enumeration defining the types of token.
Definition: token.H:76
Foam::ISstream::flags
virtual ios_base::fmtflags flags() const
Return flags of output stream.
Definition: ISstream.C:1078
Foam::ISstream::read
virtual Istream & read(token &t)
Return next token from stream.
Definition: ISstream.C:530
errLen
static constexpr const unsigned errLen
Definition: ISstream.C:38
Foam::token::END_LIST
End list [isseparator].
Definition: token.H:156
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
Foam::PtrListOps::get
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
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:473
IOWarningInFunction
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
Definition: messageStream.H:340
Foam::ISstream::beginRawRead
virtual bool beginRawRead()
Start of low-level raw binary read.
Definition: ISstream.C:1039
Foam::readUntilBalancedDelimiter
static bool readUntilBalancedDelimiter(ISstream &is, std::string &str, const bool stripComments, const char delimOpen, const char delimClose)
Definition: ISstream.C:414
Foam::token::BEGIN_LIST
Begin list [isseparator].
Definition: token.H:155
Foam::token::setType
bool setType(const tokenType tokType) noexcept
Change the token type, for similar types.
Definition: tokenI.H:317
Foam::token::punctuationToken
punctuationToken
Standard punctuation tokens (a character)
Definition: token.H:120
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:734