NumeRe v1.1.4
NumeRe: Framework für Numerische Rechnungen
includer.cpp
Go to the documentation of this file.
1/*****************************************************************************
2 NumeRe: Framework fuer Numerische Rechnungen
3 Copyright (C) 2022 Erik Haenel et al.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17******************************************************************************/
18
19#include "includer.hpp"
20#include "../symdef.hpp"
21#include "../ui/error.hpp"
22#include "../../kernel.hpp"
23
24
33void Includer::openIncludedFile(const std::string& sIncludingString)
34{
35 Match _mMatch = findCommand(sIncludingString);
36 std::string sIncludeFileName;
37
38 if (sIncludingString.front() == '@' && sIncludingString[1] != ' ')
39 {
40 // This syntax is deprecated
41 NumeReKernel::issueWarning(_lang.get("COMMON_SYNTAX_DEPRECATED", sIncludingString));
42
43 if (sIncludingString[1] == '"')
44 sIncludeFileName = sIncludingString.substr(2, sIncludingString.find('"', 2)-2);
45 else
46 sIncludeFileName = sIncludingString.substr(1, sIncludingString.find(' ')-1);
47
48 size_t offset = 4; // Corresponds to '@"C:...'
49
50 // Determine the inclusion type
51 if (sIncludingString.find(':', offset) != std::string::npos)
52 {
53 if (sIncludingString.find("defines", sIncludingString.find(':', offset)+1) != std::string::npos)
55 else if (sIncludingString.find("globals", sIncludingString.find(':', offset)+1) != std::string::npos)
57 else if (sIncludingString.find("declarations", sIncludingString.find(':', offset)+1) != std::string::npos)
59 }
60
61 // Extract the actual file name
62 if (sIncludeFileName.find(':') != std::string::npos)
63 {
64 for (int __i = sIncludeFileName.length()-1; __i >= 0; __i--)
65 {
66 if (sIncludeFileName[__i] == ':'
67 && (__i > 1
68 || (__i == 1 && sIncludeFileName.length() > (unsigned int)__i+1 && sIncludeFileName[__i+1] != '/')))
69 {
70 sIncludeFileName.erase(__i);
71 break;
72 }
73 }
74 }
75
76 // Get a valid file name
77 if (sIncludeFileName.length())
78 sIncludeFileName = FileSystem::ValidFileName(sIncludeFileName, ".nscr");
79 else
80 return;
81 }
82 else if (_mMatch.sString == "include")
83 {
84 sIncludeFileName = sIncludingString.substr(_mMatch.nPos+1+_mMatch.sString.length());
85
86 // Extract the actual file name
87 if (sIncludeFileName.find("::") != std::string::npos)
88 sIncludeFileName.erase(sIncludeFileName.find("::"));
89
90 StripSpaces(sIncludeFileName);
91
92 if (sIncludeFileName.front() == '"')
93 sIncludeFileName = sIncludeFileName.substr(1, sIncludeFileName.find('"', 1)-1);
94
95 size_t offset = _mMatch.nPos+1+_mMatch.sString.length()+3; // Corresponds to 'include "C:...'
96
97 // Determine the inclusion type
98 if (sIncludingString.find("::", offset) != std::string::npos)
99 {
100 if (sIncludingString.find("defines", sIncludingString.find("::", offset)+1) != std::string::npos)
102 else if (sIncludingString.find("globals", sIncludingString.find("::", offset)+1) != std::string::npos)
104 else if (sIncludingString.find("declarations", sIncludingString.find("::", offset)+1) != std::string::npos)
106 }
107
108 // Get a valid file name
109 if (sIncludeFileName.length())
110 sIncludeFileName = FileSystem::ValidFileName(sIncludeFileName+".*", ".nscr");
111 else
112 return;
113 }
114
115 // Open the include file
116 m_include = new StyledTextFile(sIncludeFileName);
117
118 // Ensure that the file is valid
119 if (m_include->getLastPosition() == -1)
120 {
121 delete m_include;
122 m_include = nullptr;
123 throw SyntaxError(SyntaxError::INCLUDE_NOT_EXIST, sIncludingString, SyntaxError::invalid_position, sIncludeFileName);
124 }
125}
126
127
137Includer::Includer(const std::string& sIncludingString, const std::string& sSearchPath) : m_include(nullptr), nIncludeLine(-1), m_type(Includer::INCLUDE_ALL)
138{
140
141 if (sIncludingString.front() == '@')
142 setPath(NumeReKernel::getInstance()->getScript().getPath(), false, getProgramPath());
143 else
144 setPath(sSearchPath, false, getProgramPath());
145
146 openIncludedFile(sIncludingString);
147}
148
149
155{
156 if (m_include)
157 delete m_include;
158}
159
160
169{
170 if (!is_open())
171 return "";
172
173 std::string sIncludedLine;
174
175 // Search for the next valid and non-empty line
176 // in the included script
177 while (nIncludeLine < m_include->getLinesCount() && !sIncludedLine.length())
178 {
179 std::string sCurrentLine;
180
181 // Compose lines, which were broken using the "\\" operator
182 do
183 {
184 sCurrentLine = m_include->getStrippedLine(nIncludeLine);
185 nIncludeLine++;
186 StripSpaces(sCurrentLine);
187
188 if (sIncludedLine.length() > 2 && sIncludedLine.substr(sIncludedLine.length()-2) == "\\\\")
189 sIncludedLine.erase(sIncludedLine.length()-2);
190
191 sIncludedLine += sCurrentLine;
192 }
193 while (nIncludeLine < m_include->getLinesCount()
194 && sIncludedLine.length() > 2
195 && sIncludedLine.substr(sIncludedLine.length()-2) == "\\\\");
196
197 // Ignore empty lines
198 if (!sIncludedLine.length())
199 continue;
200
201 // Ignore non-global installation sections
202 if (sIncludedLine.substr(0,9) == "<install>"
203 || (findCommand(sIncludedLine).sString == "global" && sIncludedLine.find("<install>") != std::string::npos))
204 {
205 while (nIncludeLine < m_include->getLinesCount())
206 {
207 sIncludedLine = m_include->getStrippedLine(nIncludeLine);
208 nIncludeLine++;
209 StripSpaces(sIncludedLine);
210
211 if (sIncludedLine.substr(0,12) == "<endinstall>"
212 || (findCommand(sIncludedLine).sString == "global" && sIncludedLine.find("<endinstall>") != std::string::npos))
213 break;
214 }
215
216 sIncludedLine.clear();
217 continue;
218 }
219
220 // Get the current command
221 Match _mMatch = findCommand(sIncludedLine);
222
223 // Ensure that the relevant commands are available
224 if (_mMatch.sString != "define"
225 && _mMatch.sString != "ifndef"
226 && _mMatch.sString != "ifndefined"
227 && _mMatch.sString != "redefine"
228 && _mMatch.sString != "redef"
229 && _mMatch.sString != "lclfunc"
230 && _mMatch.sString != "global"
231 && _mMatch.sString != SYMDEF_COMMAND)
232 {
233 sIncludedLine.clear();
234 continue;
235 }
236
237 // Depending on the include type, only accept the
238 // corresponding commands
239 if (m_type)
240 {
241 if (!(m_type & INCLUDE_DEFINES)
242 && (_mMatch.sString == "define"
243 || _mMatch.sString == "ifndef"
244 || _mMatch.sString == "ifndefined"
245 || _mMatch.sString == "redefine"
246 || _mMatch.sString == "redef"
247 || _mMatch.sString == "lclfunc"))
248 {
249 sIncludedLine.clear();
250 continue;
251 }
252 else if (!(m_type & INCLUDE_GLOBALS)
253 && _mMatch.sString == "global")
254 {
255 sIncludedLine.clear();
256 continue;
257 }
258 else if (!(m_type & INCLUDE_DECLARATIONS)
259 && _mMatch.sString == SYMDEF_COMMAND)
260 {
261 sIncludedLine.clear();
262 continue;
263 }
264 }
265 }
266
267 // If this is the last line, close the included file
269 {
270 delete m_include;
271 m_include = nullptr;
272 }
273
274 return sIncludedLine;
275}
276
277
286{
287 if (!m_include)
288 return false;
289
290 return true;
291}
292
293
301{
302 if (is_open())
303 return m_include->getFileName();
304
305 return "";
306}
307
308
318bool Includer::is_including_syntax(const std::string& sLine)
319{
320 if (sLine.length() > 1 && sLine.front() == '@' && sLine[1] != ' ')
321 return true;
322
323 if (findCommand(sLine).sString == "include")
324 return true;
325
326 return false;
327}
328
std::string getProgramPath() const
Definition: filesystem.hpp:127
void initializeFromKernel()
Member function to remote-initialize the class from the kernel. Cannot be used during kernel start-up...
Definition: filesystem.cpp:750
std::string getPath() const
Returns the default path of this FileSystem instance.
Definition: filesystem.cpp:547
std::string ValidFileName(std::string _sFileName, const std::string sExtension=".dat", bool checkExtension=true, bool doCleanPath=true) const
This member function evaluates, whether the passed filename is a valid filename. One may supply a pre...
Definition: filesystem.cpp:280
int setPath(std::string _sPath, bool bMkDir, std::string _sExePath)
This member function may be used to set the preferred file path of the current FileSystem instance.
Definition: filesystem.cpp:443
This class represents a file, which can be included into other files using the @ syntax.
Definition: includer.hpp:32
int m_type
Definition: includer.hpp:45
std::string getIncludedFileName() const
Returns the embedded file name.
Definition: includer.cpp:300
int nIncludeLine
Definition: includer.hpp:44
Includer(const std::string &sIncludingString, const std::string &sSearchPath)
Includer class constructor. Opens the included file defined by the passed including string.
Definition: includer.cpp:137
void openIncludedFile(const std::string &sIncludingString)
Opens the included file and determines the including type.
Definition: includer.cpp:33
~Includer()
Includer class destructor. Frees up internal memory if needed.
Definition: includer.cpp:154
@ INCLUDE_GLOBALS
Definition: includer.hpp:39
@ INCLUDE_DECLARATIONS
Definition: includer.hpp:38
@ INCLUDE_DEFINES
Definition: includer.hpp:37
bool is_open() const
Determine, if the internal included file is open and valid.
Definition: includer.cpp:285
StyledTextFile * m_include
Definition: includer.hpp:43
static bool is_including_syntax(const std::string &sLine)
Static member function which determines, whether the passed line is actually a including syntax.
Definition: includer.cpp:318
std::string getNextLine()
Return the next line of the included string.
Definition: includer.cpp:168
std::string get(const std::string &sMessage, const std::vector< std::string > &vTokens) const
This member function returns the language string for the passed language identifier and replaces all ...
Definition: language.cpp:292
static NumeReKernel * getInstance()
This static member function returns a a pointer to the singleton instance of the kernel.
Definition: kernel.hpp:221
static void issueWarning(std::string sWarningMessage)
This static function may be used to issue a warning to the user. The warning will be printed by the t...
Definition: kernel.cpp:2833
This class represents a text file in memory (e.g. a code file). This class will try to lex the loaded...
int getLastPosition() const
Returns the last printable character position in the currently loaded file.
std::string getStrippedLine(size_t line) const
Returns the selected line (without the line termination characters and without any comments).
int getLinesCount() const
Returns the number of lines in the current loaded file.
std::string getFileName() const
Returns the filename of the respresented file in memory.
Common exception class for all exceptions thrown in NumeRe.
Definition: error.hpp:32
@ INCLUDE_NOT_EXIST
Definition: error.hpp:146
static size_t invalid_position
Definition: error.hpp:235
Language _lang
Definition: kernel.cpp:39
void StripSpaces(std::string &)
Removes leading and trailing white spaces and tabulator characters.
Structure for the findCommand function.
unsigned int nPos
std::string sString
#define SYMDEF_COMMAND
Definition: symdef.hpp:21
Match findCommand(StringView sCmd, const std::string &sCommand)
This function is very important for the command handler.
Definition: tools.cpp:1275