dynamicCodeContext.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) 2019-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 "dynamicCodeContext.H"
30 #include "stringOps.H"
31 
32 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
33 
35 (
36  string& str,
37  const dictionary& dict
38 )
39 {
42 }
43 
44 
46 (
47  string& code,
48  label lineNum,
49  const string& file
50 )
51 {
52  ++lineNum; // Change from 0-based to 1-based
53 
54  const auto len = code.length();
55 
56  if (lineNum > 0 && len && !file.empty())
57  {
58  code = "#line " + Foam::name(lineNum) + " \"" + file + "\"\n" + code;
59 
60  return (code.length() - len);
61  }
62 
63  return 0;
64 }
65 
66 
68 (
69  string& code,
70  label lineNum,
71  const dictionary& dict
72 )
73 {
74  return addLineDirective(code, lineNum, dict.name());
75 }
76 
77 
78 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
79 
81 :
82  dict_(std::cref<dictionary>(dictionary::null))
83 {}
84 
85 
87 :
89 {
90  setCodeContext(dict);
91 }
92 
93 
94 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
95 
97 {
98  return &(dict_.get()) != &(dictionary::null);
99 }
100 
101 
103 {
104  return this->dict().findEntry(key, keyType::LITERAL);
105 }
106 
107 
109 (
110  const word& key,
111  string& str,
112  bool mandatory,
113  bool withLineNum
114 )
115 {
116  str.clear();
117  sha1_.append("<" + key + ">");
118 
119  const dictionary& dict = this->dict();
120  const entry* eptr = dict.findEntry(key, keyType::LITERAL);
121 
122  if (!eptr)
123  {
124  if (mandatory)
125  {
127  << "Entry '" << key << "' not found in dictionary "
128  << dict.name() << nl
129  << exit(FatalIOError);
130  }
131 
132  return false;
133  }
134 
135  // Expand dictionary entries.
136  // Removing any leading/trailing whitespace is necessary for compilation
137  // options, but is also convenient for includes and code body.
138 
139  eptr->readEntry(str);
141  sha1_.append(str);
142 
143  if (withLineNum)
144  {
145  addLineDirective(str, eptr->startLineNumber(), dict);
146  }
147 
148  return true;
149 }
150 
151 
153 (
154  const word& key,
155  string& str,
156  bool withLineNum
157 )
158 {
159  return readEntry(key, str, false, withLineNum);
160 }
161 
162 
164 {
165  dict_ = std::cref<dictionary>(dict);
166  sha1_.clear();
167 
168  // No #line for options (Make/options)
169  readIfPresent("codeOptions", codeOptions_, false);
170 
171  // No #line for libs (LIB_LIBS)
172  readIfPresent("codeLibs", codeLibs_, false);
173 
174  readIfPresent("codeInclude", codeInclude_);
175  readIfPresent("localCode", localCode_);
176  readIfPresent("code", code_);
177 }
178 
179 
180 // ************************************************************************* //
void readEntry(T &val) const
Assign to T val, FatalIOError if the number of tokens is incorrect.
Definition: entry.H:353
bool good() const noexcept
Not using dummy code context (dictionary::null)
dynamicCodeContext()
Default construct.
dictionary dict
static std::string::size_type length(const char *s)
Length of the character sequence (with nullptr protection)
Definition: string.H:258
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
void setCodeContext(const dictionary &dict)
Set code context from a dictionary.
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
virtual label startLineNumber() const =0
Return line number of first token in dictionary.
void inplaceTrim(std::string &s)
Trim leading and trailing whitespace inplace.
Definition: stringOps.C:1054
const fileName & name() const noexcept
The dictionary name.
Definition: dictionaryI.H:41
const entry * findEntry(const word &key) const
Locate literal dictionary entry, nullptr if not found.
const dictionary & dict() const noexcept
Return the parent dictionary context.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
A class for handling words, derived from Foam::string.
Definition: word.H:63
static const dictionary null
An empty dictionary, which is also the parent for all dictionaries.
Definition: dictionary.H:474
String literal.
Definition: keyType.H:82
const direction noexcept
Definition: Scalar.H:258
void inplaceExpand(std::string &s, const HashTable< string > &mapping, const char sigil='$')
Inplace expand occurrences of variables according to the mapping. Does not use environment values...
Definition: stringOps.C:718
static unsigned addLineDirective(string &code, label lineNum, const string &file)
Prefix a #line directive to code.
Encapsulation of dynamic code dictionaries.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:627
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:103
meshDefDict readIfPresent("polyMeshPatches", polyPatchNames)
const entry * findEntry(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry (const access) with the given keyword.
Definition: dictionaryI.H:84
bool readEntry(const word &key, string &str, bool mandatory=true, bool withLineNum=true)
Read string entry from context dictionary append content to SHA1 hashing and add line number etc...
static void inplaceExpand(string &str, const dictionary &dict)
Cleanup string and expand with dictionary parameters.
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:63
bool readIfPresent(const word &key, string &str, bool withLineNum=true)
Read optional string entry from context dictionary, append content to SHA1 hashing and add line numbe...
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...