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-------------------------------------------------------------------------------
11License
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
38static constexpr const unsigned errLen = 80;
39
40
41// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
42
43namespace
44{
45
46// Convert a single character to a word with length 1
47inline Foam::word charToWord(char c)
48{
49 return Foam::word(std::string(1, c), false);
50}
51
52
53// Permit slash-scoping of entries
54inline bool validVariableChar(char c)
55{
56 return (Foam::word::valid(c) || c == '/');
57}
58
59
60inline 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
111char 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
165namespace 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.
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
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...'
264 }
265 else if (lookahead == token::END_BLOCK)
266 {
267 // Looks like '${}'
269 << "Ignoring empty ${}" << endl;
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
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
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, '}')
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
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
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
647 }
648 }
649 else
650 {
651 // '#' followed by non-word. Just ignore leading '#'?
652 putback(nextC);
653
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
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
1020Foam::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
1030Foam::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 {
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
1078std::ios_base::fmtflags Foam::ISstream::flags() const
1079{
1080 return is_.flags();
1081}
1082
1083
1084std::ios_base::fmtflags Foam::ISstream::flags(const ios_base::fmtflags f)
1085{
1086 return is_.flags(f);
1087}
1088
1089
1090// ************************************************************************* //
static constexpr const unsigned errLen
Definition: ISstream.C:38
bool bad() const noexcept
True if stream is corrupted.
Definition: IOstream.H:251
Generic input stream using a standard (STL) stream.
Definition: ISstream.H:58
ISstream & get(char &c)
Raw, low-level get character function.
Definition: ISstreamI.H:56
virtual bool endRawRead()
End of low-level raw binary read.
Definition: ISstream.C:1055
ISstream & putback(const char c)
Raw, low-level putback character function.
Definition: ISstreamI.H:106
int peek()
Raw, low-level peek function.
Definition: ISstreamI.H:70
ISstream & getLine(std::string &str, char delim='\n')
Raw, low-level getline (until delimiter) into a string.
Definition: ISstreamI.H:76
bool seekCommentEnd_Cstyle()
Discard until end of C-style comment '*‍/'.
Definition: ISstream.C:79
virtual void rewind()
Rewind the stream so that it may be read again.
Definition: ISstream.C:1064
bool continueReadUntilRightBrace(std::string &str, const bool stripComments=true)
Definition: ISstream.C:513
virtual bool beginRawRead()
Start of low-level raw binary read.
Definition: ISstream.C:1039
virtual Istream & readRaw(char *data, std::streamsize count)
Low-level raw binary read.
Definition: ISstream.C:1030
virtual ios_base::fmtflags flags() const
Return flags of output stream.
Definition: ISstream.C:1078
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:64
bool getBack(token &tok)
Get the put-back token if there is one.
Definition: Istream.C:92
virtual Istream & read(token &)=0
Return next token from stream.
virtual bool read()
Re-read model coefficients if they have changed.
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
bool valid() const
True if all internal ids are non-negative.
A token holds an item read from Istream.
Definition: token.H:69
tokenType
Enumeration defining the types of token.
Definition: token.H:77
@ ERROR
Token error encountered.
Definition: token.H:79
@ VARIABLE
Definition: token.H:98
@ EXPRESSION
Definition: token.H:96
@ VERBATIM
Definition: token.H:100
@ DIRECTIVE
Definition: token.H:94
label lineNumber() const noexcept
The line number for the token.
Definition: tokenI.H:391
punctuationToken
Standard punctuation tokens (a character)
Definition: token.H:121
@ DIVIDE
Divide [isseparator].
Definition: token.H:141
@ BEGIN_BLOCK
Begin block [isseparator].
Definition: token.H:159
@ BEGIN_SQR
Begin dimensions [isseparator].
Definition: token.H:157
@ COLON
Colon [isseparator].
Definition: token.H:127
@ END_BLOCK
End block [isseparator].
Definition: token.H:160
@ HASH
Hash - directive or start verbatim string.
Definition: token.H:130
@ ASSIGN
Assignment/equals [isseparator].
Definition: token.H:137
@ END_STATEMENT
End entry [isseparator].
Definition: token.H:154
@ BEGIN_LIST
Begin list [isseparator].
Definition: token.H:155
@ PLUS
Addition [isseparator].
Definition: token.H:138
@ DOLLAR
Dollar - start variable or expression.
Definition: token.H:131
@ DQUOTE
Double quote.
Definition: token.H:135
@ END_LIST
End list [isseparator].
Definition: token.H:156
@ END_SQR
End dimensions [isseparator].
Definition: token.H:158
@ MULTIPLY
Multiply [isseparator].
Definition: token.H:140
@ NL
Newline [isspace].
Definition: token.H:124
@ MINUS
Subtract or start of negative number.
Definition: token.H:139
@ COMMA
Comma [isseparator].
Definition: token.H:129
void setBad()
Clear token and set to be ERROR.
Definition: tokenI.H:734
bool setType(const tokenType tokType) noexcept
Change the token type, for similar types.
Definition: tokenI.H:317
bool isCompound() const noexcept
Token is COMPOUND.
Definition: tokenI.H:716
A class for handling words, derived from Foam::string.
Definition: word.H:68
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
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))
System signed integer.
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
const dimensionedScalar c
Speed of light in a vacuum.
Namespace for OpenFOAM.
static Foam::word charToWord(char c)
Definition: UIPstreamBase.C:41
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
double doubleScalar
A typedef for double.
Definition: scalarFwd.H:48
static ISstream & readVerbatim(ISstream &is, std::string &str)
Definition: ISstream.C:173
bool isspace(char c) noexcept
Test for whitespace (C-locale)
Definition: char.H:65
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
static token::tokenType readVariable(ISstream &is, std::string &str, char c)
Definition: ISstream.C:235
float floatScalar
A typedef for float.
Definition: scalarFwd.H:45
static bool readUntilBalancedDelimiter(ISstream &is, std::string &str, const bool stripComments, const char delimOpen, const char delimClose)
Definition: ISstream.C:414
IOerror FatalIOError
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
word format(conversionProperties.get< word >("format"))
labelList f(nPoints)