NumeRe v1.1.4
NumeRe: Framework für Numerische Rechnungen
script.cpp
Go to the documentation of this file.
1/*****************************************************************************
2 NumeRe: Framework fuer Numerische Rechnungen
3 Copyright (C) 2014 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
20// Implementation der Script-Klasse
21
22#include "version.h"
23#include "script.hpp"
24#include "../kernel.hpp"
25#include "utils/tools.hpp"
27
28#include <algorithm>
29
30using namespace std;
31
32
36Script::Script() : FileSystem(), _localDef(true)
37{
38 bValidScript = false;
39 bLastScriptCommand = false;
40 isInstallMode = false;
43 nLine = 0;
44}
45
46
51{
52 if (m_script)
53 {
55 }
56}
57
58
67void Script::openScript(string& _sScriptFileName)
68{
69 // Close an already opened script
70 if (m_script)
71 close();
72
73 _sScriptFileName = ValidFileName(_sScriptFileName, ".nscr");
74
75 // Open the script, if the script file name exists
76 if (_sScriptFileName.length())
77 {
78 m_script.reset(new StyledTextFile(_sScriptFileName));
79
80 // Ensure that the script exists and is a valid file
81 if (m_script->getLastPosition() == -1)
82 {
83 close();
85 }
86
87 // Set the defaults
88 sScriptFileName = _sScriptFileName;
89 bValidScript = true;
91 sHelpID = "";
92 sInstallID = "";
93 nLine = 0;
96 }
97}
98
99
108{
109 // If a script is open
110 if (m_script)
111 {
112 // Close the file streams
113 m_script.reset();
114
115 if (m_include)
116 m_include.reset();
117
118 // If the file stream of the installation log
119 // is still open, add a installation failed message
120 // to it and close it afterwards
121 if (m_logger.is_open())
122 {
123 m_logger.push("--- INSTALLATION FAILED ---\n\n\n");
124 m_logger.close();
126 }
127
128 // If this is a chained installation (a.k.a. installing
129 // multiple packages), then we don't want to reset the
130 // flags but open the next script instead
131 if (vInstallPackages.size() > nCurrentPackage+1)
132 {
133 bLastScriptCommand = false;
135
136 // Open the file and hope, it
137 // actually exist
139
140 return;
141 }
142
143 if (vInstallPackages.size())
144 {
147 }
148
149 // This was the last package
150 vInstallPackages.clear();
151 nCurrentPackage = 0;
152
153 // Reset the flags
154 bValidScript = false;
155 isInstallMode = false;
157 sHelpID.clear();
158 sInstallID.clear();
159 nLine = 0;
161 _symdefs.clear();
162 }
163}
164
165
177{
178 if (m_script)
179 {
180 if (m_logger.is_open())
181 {
182 m_logger.push("--- INSTALLATION TERMINATED SUCCESSFULLY ---\n\n\n");
183 m_logger.close();
184
186 NumeReKernel::print(toSystemCodePage(_lang.get("SCRIPT_INSTALL_SUCCESS")));
187
189 }
190
191 close();
192 }
193}
194
195
204bool Script::startInstallation(string& sScriptCommand)
205{
206 // Open the installation logfile
207 if (!m_logger.open(sTokens[0][1] + "\\install.log"))
208 throw SyntaxError(SyntaxError::CANNOT_OPEN_LOGFILE, sScriptCommand, SyntaxError::invalid_position, sTokens[0][1] + "\\install.log");
209
210 // Write the first line
211 m_logger.push_line("--- INSTALLATION " + getTimeStamp(false) + " ---");
212 isInInstallSection = true;
213
214 // Remove the install tag and strip the white spaces
215 sScriptCommand = sScriptCommand.substr(9);
216 StripSpaces(sScriptCommand);
217
218 if (!sScriptCommand.length())
219 return false;
220
221 // Try to find the install information tag set
222 if (sScriptCommand.find("<info>") == string::npos)
223 {
224 sScriptCommand = "";
225 return false;
226 }
227 else
228 {
229 // If the install information tags were found
230 // handle them here
231 return handleInstallInformation(sScriptCommand);
232 }
233
234 return true;
235}
236
237
247bool Script::handleInstallInformation(string& sScriptCommand)
248{
249 unsigned int nNumereVersion = AutoVersion::MAJOR*100+AutoVersion::MINOR*10+AutoVersion::BUILD;
250 unsigned int nRequiredVersion = nNumereVersion;
251
252 // If the current install information string is incomplete
253 // (i.e. no "<endinfo>" tag), then search for the corresponding
254 // tag in the next lines
255 if (sScriptCommand.find("<endinfo>") == string::npos)
256 {
257 std::string sTemp;
258
259 // Read lines from the script until the "<endinfo>" tag was found
260 while (nLine < m_script->getLinesCount())
261 {
262 sTemp = m_script->getStrippedLine(nLine);
263 nLine++;
264 StripSpaces(sTemp);
265
266 if (sTemp.find("<endinfo>") == string::npos)
267 sScriptCommand += " " + sTemp;
268 else
269 {
270 sScriptCommand += " " + sTemp.substr(0, sTemp.find("<endinfo>") + 9);
271 break;
272 }
273 }
274 }
275
276 // Ensure that an "<endinfo>" tag was found
277 if (sScriptCommand.find("<endinfo>") == string::npos)
278 {
280 }
281
282 // Extract the install information string and the installation ID
283 std::string sInstallInfoString = sScriptCommand.substr(sScriptCommand.find("<info>")+6, sScriptCommand.find("<endinfo>")-sScriptCommand.find("<info>")-6);
284 sScriptCommand = sScriptCommand.substr(sScriptCommand.find("<endinfo>")+9);
285 sInstallID = getArgAtPos(sInstallInfoString, sInstallInfoString.find("name=")+5);
286
287 // Check whether it is necessary to install this package
288 if (sInstallInfoString.find("-version=") != std::string::npos)
289 {
290 size_t nPackageVersion = versionToInt(getArgAtPos(sInstallInfoString, sInstallInfoString.find("-version=")+9));
291
292 // Get all installed packages
293 const std::vector<Package>& vInstalledPackages = NumeReKernel::getInstance()->getInstalledPackages();
294
295 // Try to detect a match
296 for (const auto& package : vInstalledPackages)
297 {
298 if (package.getName() == sInstallID)
299 {
300 if (versionToInt(package.sVersion) >= nPackageVersion)
301 {
302 isInInstallSection = false;
303 return false;
304 }
305
306 break;
307 }
308 }
309 }
310
311 // Determine, whether the current installation needs additional packages
312 if (sInstallInfoString.find("requirepackages=") != string::npos)
313 {
314 // Get the required packages list
315 string sInstallPackages = getArgAtPos(sInstallInfoString, sInstallInfoString.find("requirepackages=")+16);
316
317 // Read all required packages
318 while (sInstallPackages.length())
319 {
320 // Get the next dependency
321 string sPackage = getNextArgument(sInstallPackages, true);
322
323 // Try to find the package in the packages
324 // folder first before using the main folder
325 if (fileExists(ValidFileName("packages/" + sPackage, ".nscr")))
326 sPackage = ValidFileName("packages/" + sPackage, ".nscr");
327 else
328 sPackage = ValidFileName(sPackage, ".nscr");
329
330 if (!sPackage.length())
331 continue;
332
333 // If this is the first package, simply append it
334 if (!vInstallPackages.size())
335 {
337 vInstallPackages.push_back(sPackage);
338 }
339 else if (std::find(vInstallPackages.begin(), vInstallPackages.end(), sPackage) == vInstallPackages.end())
340 vInstallPackages.push_back(sPackage);
341 }
342 }
343
344 // Determine, whether a version of NumeRe is required
345 if (sInstallInfoString.find("requireversion=") != string::npos)
346 nRequiredVersion = versionToInt(getArgAtPos(sInstallInfoString, sInstallInfoString.find("requireversion=")+15));
347
348 // Throw an error, if the current version if NumeRe is too old
349 if (nRequiredVersion > nNumereVersion)
351
352 // Examine the license information
353 if (sInstallInfoString.find("license=") != std::string::npos)
354 {
355 std::string sLicense = getArgAtPos(sInstallInfoString, sInstallInfoString.find("license=")+8);
356 NumeReKernel::print(LineBreak(_lang.get("SCRIPT_INSTALL_LICENSE_AGREEMENT", sInstallID, sLicense), NumeReKernel::getInstance()->getSettings()));
358
359 std::string sAnswer;
360 NumeReKernel::getline(sAnswer);
361
362 if (sAnswer.substr(0, 1) != _lang.YES())
363 {
364 NumeReKernel::print(_lang.get("SCRIPT_INSTALL_ABORT"));
365 close();
366 return false;
367 }
368 }
369
370 evaluateInstallInformation(sInstallInfoString);
371
372 if (sInstallInfoString.length())
374
375 if (!sScriptCommand.length())
376 return false;
377 return true;
378}
379
380
390void Script::writeDocumentationArticle(string& sScriptCommand)
391{
392 std::vector<std::string> vDocFileContents;
393
394 // Depending on whether the whole file was written in
395 // one line or multiple script lines
396 if (sScriptCommand.find("</helpfile>") != std::string::npos)
397 {
398 sScriptCommand.erase(sScriptCommand.find("</helpfile>")+11);
399 sScriptCommand.erase(0, 10);
400
401 vDocFileContents.push_back(sScriptCommand);
402 }
403 else
404 {
405 vDocFileContents.push_back(sScriptCommand.substr(10));
406 std::string sTemp;
407
408 // Read the contents linewise from the script
409 while (nLine < m_script->getLinesCount())
410 {
411 sTemp = m_script->getStrippedLine(nLine);
412 nLine++;
413 StripSpaces(sTemp);
414
415 // Try to find the end of the current documentation article
416 if (sTemp.find("</helpfile>") == std::string::npos)
417 vDocFileContents.push_back(sTemp);
418 else
419 {
420 // Append the last line
421 vDocFileContents.push_back(sTemp.substr(0,sTemp.find("</helpfile>")));
422 break;
423 }
424 }
425 }
426
427 DocumentationFile docFile(vDocFileContents);
428 std::vector<DocumentationArticle>& vArticles = docFile.getArticles();
429
430 for (size_t i = 0; i < vArticles.size(); i++)
431 {
432 if (!sHelpID.length() && vArticles[i].m_docEntry.sArticleId.length())
433 {
434 sHelpID = vArticles[i].m_docEntry.sArticleId;
435
436 // Ensure that the article ID start with the plugin prefix
437 if (sHelpID.substr(0, 5) != "plgn_" && sHelpID.substr(0, 4) != "pkg_")
438 sHelpID = "pkg_" + sHelpID;
439 }
440
441 std::string sId = vArticles[i].m_docEntry.sArticleId;
442
443 if (sId.substr(0, 5) != "plgn_" && sId.substr(0, 4) != "pkg_")
444 {
445 std::string sNewId = "pkg_" + sId;
446 vArticles[i].m_docEntry.sArticleId = sId;
447 }
448
449 if (!vArticles[i].m_keywords.size())
450 vArticles[i].m_keywords.push_back(sInstallID);
451 }
452
453 std::string sHelpfileName = "<>/docs/plugins/" + sHelpID + ".nhlp";
454 sHelpfileName = FileSystem::ValidFileName(sHelpfileName, ".nhlp");
455
456 docFile.print(sHelpfileName);
457
460 sScriptCommand.clear();
461}
462
463
472void Script::writeLayout(std::string& sScriptCommand)
473{
474 // create a valid file name
475 std::string sLayoutFileName = getArgAtPos(sScriptCommand, sScriptCommand.find_first_not_of(' ', 6));
476 sLayoutFileName = FileSystem::ValidFileName(sLayoutFileName, ".nlyt");
477 ofstream fLayoutFile(sLayoutFileName);
478
479 m_logger.push_line(">> Installing layout: \"" + sLayoutFileName + "\" ...");
480
481 // Remove the file name
482 size_t nQuotes = 0;
483
484 for (size_t i = sScriptCommand.find_first_not_of(' ', 6); i < sScriptCommand.length(); i++)
485 {
486 if (sScriptCommand[i] == '"' && sScriptCommand[i-1] != '\\')
487 nQuotes++;
488
489 if (!(nQuotes % 2) && sScriptCommand[i] == ' ')
490 {
491 sScriptCommand = "layout " + sScriptCommand.substr(i);
492 break;
493 }
494 else if (i+1 == sScriptCommand.length())
495 sScriptCommand = "layout";
496 }
497
498 // Depending on whether the whole file was written in
499 // one line or multiple script lines
500 if (sScriptCommand.find("endlayout") != string::npos)
501 {
502 sScriptCommand.erase(sScriptCommand.find("endlayout")+9);
503
504 // Write the contents to the documentation article file
505 if (!fLayoutFile.fail())
506 {
508 m_logger.push_line(">> >> Copying: " + sScriptCommand + " ...");
509
510 fLayoutFile << sScriptCommand << endl;
511 }
512 else
513 {
514 fLayoutFile.close();
515 throw SyntaxError(SyntaxError::CANNOT_READ_FILE, sScriptCommand, SyntaxError::invalid_position, sLayoutFileName);
516 }
517
518 fLayoutFile.close();
519 }
520 else
521 {
522 // Write the contents linewise to the documentation article file
523 if (!fLayoutFile.fail())
524 {
526 m_logger.push_line(">> >> Copying: " + sScriptCommand + " ...");
527
528 fLayoutFile << sScriptCommand << endl;
529
530 string sTemp;
531 size_t nIndent = 1;
532
533 // Read the contents linewise from the script
534 while (nLine < m_script->getLinesCount())
535 {
536 sTemp = m_script->getLine(nLine);
537 nLine++;
538 StripSpaces(sTemp);
539
541 m_logger.push_line(">> >> Copying: " + sTemp + " ...");
542
543 if (sTemp.substr(0, 8) == "endgroup" || sTemp.substr(0, 9) == "endlayout")
544 nIndent--;
545
546 sTemp.insert(0, nIndent, '\t');
547
548 // Try to find the end of the current documentation article
549 if (sTemp.find("endlayout") == string::npos)
550 {
551 // Write the current line
552 fLayoutFile << sTemp << endl;
553 }
554 else
555 {
556 // Write the last line
557 fLayoutFile << sTemp.substr(0, sTemp.find("endlayout")+9) << endl;
558 break;
559 }
560
561 if (sTemp.substr(nIndent, 5) == "group")
562 nIndent++;
563 }
564 }
565 else
566 {
567 fLayoutFile.close();
568 throw SyntaxError(SyntaxError::CANNOT_READ_FILE, sScriptCommand, SyntaxError::invalid_position, sLayoutFileName);
569 }
570
571 fLayoutFile.close();
572 }
573
574 sScriptCommand.clear();
575}
576
577
586{
587 std::string sDocumentation;
589
590 // We detected the start of the procedure in
591 // the previous line. Let's compensate for
592 // this
593 nLine--;
594
595 if (nLine)
596 {
597 int line = m_script->findDocStartLine(nLine-1);
598
599 if (line > -1)
600 {
601 while (line < nLine)
602 {
603 std::string sLine = m_script->getLine(line);
604 StripSpaces(sLine);
605 sDocumentation += sLine + "\n";
606 line++;
607 }
608 }
609 }
610
611 // Write first line including prefixed documentation
612 std::string sLine = m_script->getLine(nLine);
613 StripSpaces(sLine);
614
615 m_logger.push_line(">> Installing: \"" + sLine.substr(sLine.find('$'), sLine.find('(', sLine.find('$'))-sLine.find('$')) + "\" ...");
616
618 NumeReKernel::print(toSystemCodePage(_lang.get("SCRIPT_INSTALLING_PROC", sLine.substr(sLine.find('$'), sLine.find('(', sLine.find('$'))-sLine.find('$')))));
619
621 m_logger.push_line(">> >> Copying: " + sLine + " ...");
622
623 _procedure.writeProcedure(sLine + sDocumentation);
624 nLine++;
625
626 // Write remaining lines
627 while (nLine < m_script->getLinesCount())
628 {
629 sLine = m_script->getLine(nLine);
630 nLine++;
631 StripSpaces(sLine);
632
634 m_logger.push_line(">> >> Copying: " + sLine + " ...");
635
636 _procedure.writeProcedure(sLine);
637
638 if (findCommand(m_script->getStrippedLine(nLine-1)).sString == "endprocedure")
639 break;
640 }
641}
642
643
653{
654 std::string sStartLine = m_script->getStrippedLine(nLine-1);
655 size_t pos = sStartLine.find("<file ");
656
657 if (pos == std::string::npos || sStartLine.find("name=", pos) == std::string::npos)
658 return false;
659
660 std::string sFileName = ValidizeAndPrepareName(Documentation::getArgAtPos(sStartLine, sStartLine.find("name=", pos)+5), ".nscr");
661 m_logger.push_line(">> Writing file: \"" + sFileName + "\" ...");
662 std::vector<std::string> vFileContents;
663 size_t nIndent = UINT_MAX;
664
665 // Buffer the files contents and determine the minimal indent, which may be
666 // removed
667 while (nLine < m_script->getLinesCount())
668 {
669 // Get the contents and replace all tab characters with 4 whitespaces
670 // (more secure, because users might prefer whitespaces)
671 vFileContents.push_back(m_script->getLine(nLine));
672 replaceAll(vFileContents.back(), "\t", " ");
673
674 // Find the first non-whitespace character
675 size_t nFirstChar = vFileContents.back().find_first_not_of(' ');
676
677 // Determine, if it is smaller than the already
678 // determined index
679 if (nFirstChar < nIndent)
680 nIndent = nFirstChar;
681
683 m_logger.push_line(">> >> Copying: " + vFileContents.back() + " ...");
684
685 nLine++;
686
687 if (m_script->getStrippedLine(nLine).find("<endfile>") != std::string::npos)
688 break;
689 }
690
691 nLine++;
692
693 std::ofstream wholeFile(sFileName);
694
695 // Now write the buffer to the file while removing the
696 // superfluous indent
697 for (size_t i = 0; i < vFileContents.size(); i++)
698 {
699 wholeFile << vFileContents[i].substr(nIndent) + "\n";
700 }
701
702 wholeFile.close();
703
704 return true;
705}
706
707
717void Script::evaluateInstallInformation(std::string& sInstallInfoString)
718{
719 if (sInstallInfoString.length())
720 {
721 // Evaluate the flag list
722 if (findParameter(sInstallInfoString, "flags", '='))
723 {
724 string sParam = getArgAtPos(sInstallInfoString, findParameter(sInstallInfoString, "flags", '=')+5);
725
726 if (sParam.find("ENABLE_FULL_LOGGING") != string::npos)
728
729 if (sParam.find("DISABLE_SCREEN_OUTPUT") != string::npos)
731 }
732
734 NumeReKernel::print(toSystemCodePage(_lang.get("SCRIPT_START_INSTALL")) + " ...");
735 }
736
737 // Write the installation information string to the
738 // installation logfile
739 if (sInstallInfoString.length())
740 m_logger.push_line("Installinfo: " + sInstallInfoString);
741}
742
743
752{
753 std::string sScriptCommand;
754
755 // Search for the next valid and non-empty line
756 // in the current script
757 while (m_script && nLine < m_script->getLinesCount() && !sScriptCommand.length())
758 {
759 string sCurrentLine;
760
761 // Compose lines, which were broken using the "\\" operator
762 do
763 {
764 sCurrentLine = m_script->getStrippedLine(nLine);
765 nLine++;
766 StripSpaces(sCurrentLine);
767
768 if (sScriptCommand.length() > 2 && sScriptCommand.substr(sScriptCommand.length()-2) == "\\\\")
769 sScriptCommand.erase(sScriptCommand.length()-2);
770
771 sScriptCommand += sCurrentLine;
772
773 // Add a breakpoint, if the user has set it in the editor
774 if (NumeReKernel::getInstance()->getDebugger().getBreakpointManager().isBreakpoint(sScriptFileName, nLine-1) && sScriptCommand.substr(0,2) != "|>")
775 sScriptCommand.insert(0, "|> ");
776 }
777 while (nLine < m_script->getLinesCount() && sScriptCommand.length() > 2 && sScriptCommand.substr(sScriptCommand.length()-2) == "\\\\");
778
779 // Ignore empty lines
780 if (!sScriptCommand.length())
781 continue;
782
783 // If we find the installation section, then either jump over it
784 // or execute it, if the user wants to do so
785 if (sScriptCommand.substr(0,9) == "<install>" && !isInstallMode)
786 {
787 // jump over the installation section
788 while (nLine < m_script->getLinesCount())
789 {
790 sScriptCommand = m_script->getStrippedLine(nLine);
791 nLine++;
792 StripSpaces(sScriptCommand);
793
794 if (sScriptCommand.substr(0,12) == "<endinstall>")
795 break;
796 }
797
798 sScriptCommand.clear();
799 continue;
800 }
801 else if (sScriptCommand.substr(0,9) == "<install>")
802 {
803 // Execute the installation section
804 if (!startInstallation(sScriptCommand))
805 {
806 // Obviously already installed
808 {
809 bool shallReturn = false;
810
811 // jump over the installation section
812 while (nLine < m_script->getLinesCount())
813 {
814 sScriptCommand = m_script->getStrippedLine(nLine);
815 nLine++;
816 StripSpaces(sScriptCommand);
817
818 if (sScriptCommand.substr(0,12) == "<endinstall>")
819 break;
820
821 if (findCommand(sScriptCommand).sString == "return")
822 shallReturn = true;
823 else if (sScriptCommand.length())
824 shallReturn = false;
825 }
826
827 if (m_logger.is_open())
828 {
829 m_logger.push("--- NOT INSTALLED: NEWER OR SAME VERSION ALREADY AVAILABLE ---\n\n\n");
830 m_logger.close();
831 }
832
833 if (shallReturn)
834 {
835 bLastScriptCommand = true;
836 close();
837 return "";
838 }
839
840 sScriptCommand.clear();
841 }
842
843 continue;
844 }
845 }
846
847 // Get the installation information
848 if (sScriptCommand.substr(0,6) == "<info>" && isInstallMode && isInInstallSection)
849 {
850 if (!handleInstallInformation(sScriptCommand))
851 {
852 // Obviously already installed
854 {
855 bool shallReturn = false;
856
857 // jump over the installation section
858 while (nLine < m_script->getLinesCount())
859 {
860 sScriptCommand = m_script->getStrippedLine(nLine);
861 nLine++;
862 StripSpaces(sScriptCommand);
863
864 if (sScriptCommand.substr(0,12) == "<endinstall>")
865 break;
866
867 if (findCommand(sScriptCommand).sString == "return")
868 shallReturn = true;
869 else if (sScriptCommand.length())
870 shallReturn = false;
871 }
872
873 if (m_logger.is_open())
874 {
875 m_logger.push("--- NOT INSTALLED: NEWER OR SAME VERSION ALREADY AVAILABLE ---\n\n\n");
876 m_logger.close();
877 }
878
879 if (shallReturn)
880 {
881 bLastScriptCommand = true;
882 close();
883 return "";
884 }
885
886 sScriptCommand.clear();
887 }
888
889 continue;
890 }
891 }
892
893 // Write a whole file from script to file
894 if (sScriptCommand.substr(0,6) == "<file " && isInstallMode && isInInstallSection)
895 {
896 if (writeWholeFile())
897 {
898 sScriptCommand.clear();
899 continue;
900 }
901 }
902
903 // Write the documentation articles to their corresponding files
904 if (sScriptCommand.substr(0,10) == "<helpfile>" && isInstallMode && isInInstallSection)
905 {
906 writeDocumentationArticle(sScriptCommand);
907 continue;
908 }
909
910 // Write window layouts
911 if (findCommand(sScriptCommand).sString == "layout" && isInstallMode && isInInstallSection)
912 {
913 writeLayout(sScriptCommand);
914 continue;
915 }
916
917 // Write procedures
918 if (findCommand(sScriptCommand).sString == "procedure" && isInstallMode && isInInstallSection)
919 {
921 sScriptCommand.clear();
922 continue;
923 }
924
925 // End the installation
926 if (sScriptCommand.substr(0, 12) == "<endinstall>" && isInstallMode && isInInstallSection)
927 {
928 if (m_logger.is_open())
929 {
930 m_logger.push("--- INSTALLATION TERMINATED SUCCESSFULLY ---\n\n\n");
931 m_logger.close();
932
934 NumeReKernel::print(toSystemCodePage(_lang.get("SCRIPT_INSTALL_SUCCESS")));
935
937 }
938
939 isInInstallSection = false;
940 sScriptCommand = sScriptCommand.substr(12);
941
942 if (!sScriptCommand.length())
943 continue;
944 }
946 m_logger.push_line(">> Evaluating: " + sScriptCommand + " ...");
947 }
948
949 // close the script, if this is the last command
950 if (!m_script || nLine >= m_script->getLinesCount())
951 {
952 bLastScriptCommand = true;
954 }
955
956 return sScriptCommand;
957}
958
959
968{
969 if (m_include && m_include->is_open())
970 return m_include->getNextLine();
971
972 return "";
973}
974
975
985string Script::handleIncludeSyntax(string& sScriptCommand)
986{
987 // Only accept the including syntax, if we're currently
988 // not from another included file
989 if (!m_include && Includer::is_including_syntax(sScriptCommand))
990 {
991 // Open the include file
992 std::string sFileName = m_script->getFileName();
993 m_include.reset(new Includer(sScriptCommand, sFileName.substr(0, sFileName.rfind('/'))));
994
995 // Ensure that the file is valid
996 if (!m_include->is_open())
997 {
998 m_include.reset();
999 throw SyntaxError(SyntaxError::SCRIPT_NOT_EXIST, sScriptCommand, SyntaxError::invalid_position, sScriptCommand);
1000 }
1001
1002 return "";
1003 }
1004
1005 return sScriptCommand;
1006}
1007
1008
1018bool Script::handleLocalDefinitions(string& sScriptCommand)
1019{
1020 std::string sCommand = findCommand(sScriptCommand).sString;
1021
1022 // If the current command contains the command "lclfunc",
1023 // then this is a definition
1024 if (sCommand == "lclfunc")
1025 {
1026 _localDef.defineFunc(sScriptCommand.substr(sCommand.length()));
1027 sScriptCommand.clear();
1028 return false;
1029 }
1030 else if (sCommand == SYMDEF_COMMAND)
1031 {
1032 _symdefs.createSymbol(sScriptCommand.substr(sCommand.length()));
1033 sScriptCommand.clear();
1034 return false;
1035 }
1036 else
1037 {
1038 // Simply replace the current call
1039 _symdefs.resolveSymbols(sScriptCommand);
1040 return _localDef.call(sScriptCommand);
1041 }
1042
1043 return true;
1044}
1045
1046
1056{
1057 std::string sScriptCommand = "";
1058
1059 // Get the next script command
1060 if (m_script)
1061 {
1062 if (!m_include || !m_include->is_open())
1063 {
1064 // Delete the includer, if it is not needed anymore
1065 if (m_include)
1066 m_include.reset();
1067
1068 // Get the next script command from the currently opened script
1069 sScriptCommand = getNextScriptCommandFromScript();
1070 }
1071 else
1072 {
1073 // Get the next include string from the included script
1074 sScriptCommand = getNextScriptCommandFromInclude();
1075 }
1076 }
1077 else
1078 return "";
1079
1080 // Replace "<this>" path tokens with the current script file path
1081 while (sScriptCommand.find("<this>") != string::npos)
1082 sScriptCommand.replace(sScriptCommand.find("<this>"), 6, sScriptFileName.substr(0, sScriptFileName.rfind('/')));
1083
1084 // Handle the include syntax ("@SOMESCRIPT") and everything, what
1085 // belongs to it
1086 sScriptCommand = handleIncludeSyntax(sScriptCommand);
1087
1088 // Ensure that procedures are not written accidentally
1089 if (!isInstallMode
1090 && sScriptCommand.find("procedure") != string::npos
1091 && sScriptCommand.find('$', sScriptCommand.find("procedure")) != string::npos)
1093
1094 // If we're not installing, replace all local functions
1095 if (!isInstallMode)
1096 {
1097 if (!handleLocalDefinitions(sScriptCommand))
1098 return "";
1099 }
1100
1101 // Return the script command for evaluation
1102 return sScriptCommand;
1103}
1104
1105
1106
This class represents a whole documentation file with its contained documentation articles.
Definition: docfile.hpp:61
void print(const std::string &sFileName)
Print the documentation file to the specified file.
Definition: docfile.cpp:336
std::vector< DocumentationArticle > & getArticles()
Get all articles present in the current documentation file.
Definition: docfile.hpp:81
void addFileToDocumentationIndex(const std::string &sFileName)
This member function is used to add documentation index entries to the index during a plugin or packa...
Definition: doc_helper.cpp:498
static std::string getArgAtPos(const std::string &sCmd, unsigned int pos)
This static member is a fallback for the XML-parsing logic-stuff.
Definition: doc_helper.cpp:382
This class implements the basic input/ output file system and provides functionalities to work with f...
Definition: filesystem.hpp:92
std::string ValidizeAndPrepareName(const std::string &_sFileName, const std::string &sExtension=".dat") const
This member function validizes the passed file name and creates the needed folders on-the-fly.
Definition: filesystem.cpp:424
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
std::string sTokens[7][2]
Definition: filesystem.hpp:100
bool reset()
This member function resets the FunctionDefinitionManager object to a state before any function was d...
Definition: define.cpp:1040
bool defineFunc(const std::string &sExpr, bool bRedefine=false, bool bFallback=false)
This function defines a custom function, by passing it to a new FunctionDefinition class instance.
Definition: define.cpp:655
bool call(std::string &sExpr, int nRecursion=0)
This function searches for known custom definitions in the passed expression and replaces them with t...
Definition: define.cpp:801
This class represents a file, which can be included into other files using the @ syntax.
Definition: includer.hpp:32
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 YES() const
Definition: language.hpp:197
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
void push(const std::string &sMessage)
Push a message to the logger stream. Will automatically re-open a file, if the stream had been closed...
Definition: logger.cpp:162
bool is_open() const
Check, whether the logger stream is currently open.
Definition: logger.cpp:131
void push_line(const std::string &sMessage)
Push a line to the logger stream. The stream will automatically append the line termination character...
Definition: logger.cpp:178
bool open(const std::string &sLogFile)
Open the target logging file for writing.
Definition: logger.cpp:100
void close()
Close the logger stream.
Definition: logger.cpp:118
static NumeReKernel * getInstance()
This static member function returns a a pointer to the singleton instance of the kernel.
Definition: kernel.hpp:221
static void getline(std::string &sLine)
This function is an implementation replacing the std::getline() function.
Definition: kernel.cpp:3621
static void printPreFmt(const std::string &__sLine, bool printingEnabled=true)
This member function appends the pre- formatted string to the buffer and informs the terminal that we...
Definition: kernel.cpp:2683
static void installationDone()
Notify the GUI that the installation was processed.
Definition: kernel.cpp:3159
static void print(const std::string &__sLine, bool printingEnabled=true)
This member function appends the passed string as a new output line to the buffer and informs the ter...
Definition: kernel.cpp:2636
const std::vector< Package > & getInstalledPackages() const
Returns a vector containing the names and the version info of each installed plugin.
Definition: kernel.cpp:2553
Procedure & getProcedureInterpreter()
Definition: kernel.hpp:316
Settings & getSettings()
Definition: kernel.hpp:296
void addHelpIndex(const std::string &_sPluginName, std::string _sHelpId)
This member function adds the passed documentation index ID to the plugin definition.
Definition: plugin.cpp:770
bool declareNewPackage(const std::string &sInstallInfoString)
This member function declares a new plugin from the passed install information string.
Definition: plugin.cpp:664
This class implements the logic to evaluate complex procedures, which may be called recursively.
Definition: procedure.hpp:56
bool writeProcedure(std::string sProcedureLine)
This member function handles the procedure installation process by governing the file stream and pass...
Definition: procedure.cpp:1547
std::unique_ptr< Includer > m_include
Definition: script.hpp:39
FunctionDefinitionManager _localDef
Definition: script.hpp:64
bool handleInstallInformation(std::string &sScriptCommand)
This member function handles the install information tags of the current installation section.
Definition: script.cpp:247
Script()
Default constructor.
Definition: script.cpp:36
void openScript(std::string &_sScriptFileName)
This member function opens the script with the passed file name.
Definition: script.cpp:67
bool isInInstallSection
Definition: script.hpp:56
bool writeWholeFile()
Writes the contents of a whole file to the target file, which has been specified by the XML-like tags...
Definition: script.cpp:652
bool isInstallMode
Definition: script.hpp:55
void writeDocumentationArticle(std::string &sScriptCommand)
This member function writes the appended documentation article to the target file.
Definition: script.cpp:390
SymDefManager _symdefs
Definition: script.hpp:65
void writeProcedure()
Writes a procedure including the comments to a procedure file.
Definition: script.cpp:585
void evaluateInstallInformation(std::string &sInstallInfoString)
This member function evaluates the flags from the installation information string and also removes un...
Definition: script.cpp:717
bool bLastScriptCommand
Definition: script.hpp:52
unsigned int nCurrentPackage
Definition: script.hpp:62
std::string getNextScriptCommandFromInclude()
This member function returns the next valid line from the included script.
Definition: script.cpp:967
std::vector< std::string > vInstallPackages
Definition: script.hpp:61
@ ENABLE_DEFAULTS
Definition: script.hpp:43
@ ENABLE_FULL_LOGGING
Definition: script.hpp:44
@ DISABLE_SCREEN_OUTPUT
Definition: script.hpp:45
void writeLayout(std::string &sScriptCommand)
This member function writes the embedded window layout to the target file.
Definition: script.cpp:472
Logger m_logger
Definition: script.hpp:48
void close()
This member function closes an opened script.
Definition: script.cpp:107
~Script()
Destructor.
Definition: script.cpp:50
std::unique_ptr< StyledTextFile > m_script
Definition: script.hpp:38
std::string sInstallID
Definition: script.hpp:59
std::string sScriptFileName
Definition: script.hpp:49
bool bValidScript
Definition: script.hpp:51
std::string getNextScriptCommandFromScript()
This member function returns the next valid line from the currently opened script.
Definition: script.cpp:751
std::string getNextScriptCommand()
This member function is the main interface to the internal managed script. It will always return the ...
Definition: script.cpp:1055
bool startInstallation(std::string &sScriptCommand)
This member function starts the current installation section.
Definition: script.cpp:204
std::string sHelpID
Definition: script.hpp:58
int nLine
Definition: script.hpp:53
void returnCommand()
This member function closes the script, if the code reached a "return" statement.
Definition: script.cpp:176
bool handleLocalDefinitions(std::string &sScriptCommand)
This private member function handles the definition and replacement of local functions.
Definition: script.cpp:1018
int nInstallModeFlags
Definition: script.hpp:54
std::string handleIncludeSyntax(std::string &sScriptCommand)
This member function handles the script include syntax ("@SCRIPT") and prepares the included file str...
Definition: script.cpp:985
This class represents a text file in memory (e.g. a code file). This class will try to lex the loaded...
void resolveSymbols(std::string &sCommandLine) const
Resolve all file-static constant declarations in the current line.
Definition: symdef.cpp:47
void clear()
Remove all file-static constant declarations.
Definition: symdef.cpp:33
void createSymbol(const std::string &sCommandLine)
Create one or more new file-static constant declarations for the current file.
Definition: symdef.cpp:72
Common exception class for all exceptions thrown in NumeRe.
Definition: error.hpp:32
@ CANNOT_OPEN_LOGFILE
Definition: error.hpp:71
@ CANNOT_READ_FILE
Definition: error.hpp:75
@ PROCEDURE_WITHOUT_INSTALL_FOUND
Definition: error.hpp:200
@ SCRIPT_NOT_EXIST
Definition: error.hpp:204
@ INSUFFICIENT_NUMERE_VERSION
Definition: error.hpp:122
static size_t invalid_position
Definition: error.hpp:235
Language _lang
Definition: kernel.cpp:39
std::string toSystemCodePage(std::string)
Converts an internal to an external string. Does nothing currently.
bool fileExists(const string &)
This function checks, whether the file with the passed file name exists.
Definition: tools.cpp:2500
static const long MINOR
Definition: version.h:18
static const long BUILD
Definition: version.h:19
static const long MAJOR
Definition: version.h:17
void StripSpaces(std::string &)
Removes leading and trailing white spaces and tabulator characters.
int findParameter(const std::string &sCmd, const std::string &sParam, const char cFollowing)
This function searches the passed parameter in the passed command string. If something is found,...
Definition: tools.cpp:113
size_t versionToInt(std::string sVersion)
Converts a version string into a multi-digit integer.
std::string getNextArgument(std::string &sArgList, bool bCut)
Definition: tools.cpp:2294
void replaceAll(std::string &sToModify, const char *sToRep, const char *sNewValue, size_t nStart, size_t nEnd)
This function replaces all occurences of the string sToRep in the string sToModify with the new value...
std::string getTimeStamp(bool bGetStamp)
This function simple returns the current time as a default timestamp.
std::string sString
std::string toString(int)
Converts an integer to a string without the Settings bloat.
#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
string getArgAtPos(const string &sCmd, unsigned int nPos, int extraction)
Extracts a options value at the selected position and applies automatic parsing, if necessary.
Definition: tools.cpp:1598
std::string LineBreak(std::string sOutput, const Settings &_option, bool bAllowDashBreaks, int nFirstIndent, int nIndent)
This function takes a string, splits it into multiple lines if it is too long and returns the result.
Definition: tools.cpp:2205