core: on error, a crash could happen
[scilab.git] / scilab / modules / ast / src / cpp / system_env / configvariable.cpp
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2008-2008 - DIGITEO - Antoine ELIAS
4 *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13 *
14 */
15
16 #include "configvariable.hxx"
17 #include "callable.hxx"
18 #include "cell.hxx"
19 #include "context.hxx"
20 #include "execvisitor.hxx"
21 #include "macrofile.hxx"
22 #include "threadId.hxx"
23 #include "threadmanagement.hxx"
24 #include <iomanip>
25 #include <list>
26 #include <vector>
27
28 extern "C"
29 {
30 #include "FileExist.h"
31 #include "elem_common.h"
32 #include "os_string.h"
33 #include "sci_malloc.h"
34 #include "strsubst.h"
35 }
36
37 /*
38 ** Module List
39 ** \{
40 */
41 std::list<std::wstring> ConfigVariable::m_ModuleList;
42
43 void ConfigVariable::setModuleList(std::list<std::wstring>& _pModule_list)
44 {
45     m_ModuleList = _pModule_list;
46 }
47
48 std::list<std::wstring> ConfigVariable::getModuleList()
49 {
50     std::list<std::wstring> moduleList(m_ModuleList);
51     return moduleList;
52 }
53 /*
54 ** \}
55 */
56
57 /*
58 ** SCI
59 ** \{
60 */
61 std::wstring ConfigVariable::m_SCIPath;
62
63 void ConfigVariable::setSCIPath(const std::wstring& _SCIPath)
64 {
65     m_SCIPath = _SCIPath;
66 }
67
68 std::wstring& ConfigVariable::getSCIPath()
69 {
70     return m_SCIPath;
71 }
72
73 /*
74 ** \}
75 */
76
77 /*
78 ** SCIHOME
79 ** \{
80 */
81
82 std::wstring ConfigVariable::m_SCIHOME;
83
84 void ConfigVariable::setSCIHOME(const std::wstring& _SCIHOME)
85 {
86     m_SCIHOME = _SCIHOME;
87 }
88
89 std::wstring& ConfigVariable::getSCIHOME()
90 {
91     return m_SCIHOME;
92 }
93 /*
94 ** \}
95 */
96
97 /*
98 ** TMPDIR
99 ** \{
100 */
101
102 std::wstring ConfigVariable::m_TMPDIR;
103
104 void ConfigVariable::setTMPDIR(const std::wstring& _TMPDIR)
105 {
106     m_TMPDIR = _TMPDIR;
107 }
108
109 std::wstring& ConfigVariable::getTMPDIR()
110 {
111     return m_TMPDIR;
112 }
113 /*
114 ** \}
115 */
116
117 /*
118 ** Force Quit
119 ** \{
120 */
121 bool ConfigVariable::m_bForceQuit = false;
122
123 void ConfigVariable::setForceQuit(bool _bForceQuit)
124 {
125     m_bForceQuit = _bForceQuit;
126 }
127
128 bool ConfigVariable::getForceQuit(void)
129 {
130     return m_bForceQuit;
131 }
132 /*
133 ** \}
134 */
135
136 /*
137 ** Exit Status
138 ** \{
139 */
140 int ConfigVariable::m_iExitStatus = 0;
141
142 void ConfigVariable::setExitStatus(int _iExitStatus)
143 {
144     m_iExitStatus = _iExitStatus;
145 }
146
147 int ConfigVariable::getExitStatus(void)
148 {
149     return m_iExitStatus;
150 }
151 /*
152 ** \}
153 */
154
155 /*
156 ** Digit precision, ex format function
157 ** \{
158 */
159
160 int ConfigVariable::m_iFormatSize = 0;
161
162 void ConfigVariable::setFormatSize(int _iFormatSize)
163 {
164     m_iFormatSize = _iFormatSize;
165 }
166
167 int ConfigVariable::getFormatSize(void)
168 {
169     return m_iFormatSize;
170 }
171
172 int ConfigVariable::m_iFormatMode = 0;
173
174 void ConfigVariable::setFormatMode(int _iFormatMode)
175 {
176     m_iFormatMode = _iFormatMode;
177 }
178
179 int ConfigVariable::getFormatMode(void)
180 {
181     return m_iFormatMode;
182 }
183
184 /*
185 ** \}
186 */
187
188 /*
189 ** Screen console width
190 ** \{
191 */
192
193 int ConfigVariable::m_iConsoleWidth = 0;
194
195 void ConfigVariable::setConsoleWidth(int _iConsoleWidth)
196 {
197     m_iConsoleWidth = Max(ICONSOLEWIDTH_MIN, _iConsoleWidth);
198 }
199
200 int ConfigVariable::getConsoleWidth(void)
201 {
202     return m_iConsoleWidth;
203 }
204 /*
205 ** \}
206 */
207
208 /*
209 ** Screen console lines
210 ** \{
211 */
212
213 int ConfigVariable::m_iConsoleLines = 0; //console lines default value
214
215 void ConfigVariable::setConsoleLines(int _iConsoleLines)
216 {
217     m_iConsoleLines = Max(ICONSOLELINES_MIN, _iConsoleLines);
218 }
219
220 int ConfigVariable::getConsoleLines(void)
221 {
222     return m_iConsoleLines;
223 }
224 /*
225 ** \}
226 */
227
228 /*
229 ** Scilab mode
230 ** \{
231 */
232
233 int ConfigVariable::m_iScilabMode = 1; //SCILAB_API = 1  Scilab is launch as an API
234
235 void ConfigVariable::setScilabMode(int _iScilabMode)
236 {
237     m_iScilabMode = _iScilabMode;
238 }
239
240 int ConfigVariable::getScilabMode(void)
241 {
242     return m_iScilabMode;
243 }
244 /*
245 ** \}
246 */
247
248 /*
249 ** Warning Mode
250 ** \{
251 */
252 bool ConfigVariable::m_bWarningMode = true;
253
254 void ConfigVariable::setWarningMode(bool _bWarningMode)
255 {
256     m_bWarningMode = _bWarningMode;
257 }
258
259 bool ConfigVariable::getWarningMode(void)
260 {
261     return m_bWarningMode;
262 }
263 /*
264 ** \}
265 */
266 /*
267 ** \}
268 */
269
270 /*
271 ** Warning Stop
272 ** \{
273 */
274 bool ConfigVariable::m_bWarningStop = false;
275
276 void ConfigVariable::setWarningStop(bool _bWarningStop)
277 {
278     m_bWarningStop = _bWarningStop;
279 }
280
281 bool ConfigVariable::getWarningStop(void)
282 {
283     return m_bWarningStop;
284 }
285 /*
286 ** \}
287 */
288
289 /*
290 ** Old Empty Behaviour
291 ** \{
292 */
293 bool ConfigVariable::m_bOldEmptyBehaviour = false;
294
295 void ConfigVariable::setOldEmptyBehaviour(bool _bOldEmptyBehaviour)
296 {
297     m_bOldEmptyBehaviour = _bOldEmptyBehaviour;
298 }
299
300 bool ConfigVariable::getOldEmptyBehaviour(void)
301 {
302     return m_bOldEmptyBehaviour;
303 }
304 /*
305 ** \}
306 */
307
308 /*
309 ** HOME
310 ** \{
311 */
312
313 std::wstring ConfigVariable::m_HOME;
314
315 void ConfigVariable::setHOME(const std::wstring& _HOME)
316 {
317     m_HOME = _HOME;
318 }
319
320 std::wstring& ConfigVariable::getHOME()
321 {
322     return m_HOME;
323 }
324 /*
325 ** \}
326 */
327
328 /*
329 ** Clear last error information
330 ** \{
331 */
332 bool ConfigVariable::m_bLastErrorCall = false;
333
334 void ConfigVariable::setLastErrorCall(void)
335 {
336     m_bLastErrorCall = true;
337 }
338
339 void ConfigVariable::clearLastError(void)
340 {
341     //if (m_bLastErrorCall == false)
342     {
343         m_wstError = L"";
344         m_iError = 0;
345         m_iErrorLine = 0;
346         m_wstErrorFunction = L"";
347     }
348     m_bLastErrorCall = false;
349 }
350 /*
351 ** \}
352 */
353
354 /*
355 ** Last Error Message
356 ** \{
357 */
358
359 std::wstring ConfigVariable::m_wstError;
360
361 void ConfigVariable::setLastErrorMessage(const std::wstring& _wstError)
362 {
363     m_wstError = _wstError;
364 }
365
366 std::wstring& ConfigVariable::getLastErrorMessage()
367 {
368     return m_wstError;
369 }
370 /*
371 ** \}
372 */
373
374 /*
375 ** Last Error ID
376 ** \{
377 */
378 int ConfigVariable::m_iError = 0;
379 bool ConfigVariable::m_bError = false;
380
381 void ConfigVariable::setError()
382 {
383     m_bError = true;
384 }
385
386 bool ConfigVariable::isError()
387 {
388     return m_bError;
389 }
390
391 void ConfigVariable::resetError()
392 {
393     m_bError = false;
394 }
395
396 void ConfigVariable::setLastErrorNumber(int _iError)
397 {
398     m_iError = _iError;
399 }
400
401 int ConfigVariable::getLastErrorNumber(void)
402 {
403     return m_iError;
404 }
405 /*
406 ** \}
407 */
408
409 /*
410 ** Last Error Line
411 ** \{
412 */
413 int ConfigVariable::m_iErrorLine = 0;
414
415 void ConfigVariable::setLastErrorLine(int _iErrorLine)
416 {
417     m_iErrorLine = _iErrorLine;
418 }
419
420 int ConfigVariable::getLastErrorLine(void)
421 {
422     return m_iErrorLine;
423 }
424 /*
425 ** \}
426 */
427
428 /*
429 ** Last Error Function
430 ** \{
431 */
432
433 std::wstring ConfigVariable::m_wstErrorFunction = L"";
434
435 void ConfigVariable::setLastErrorFunction(const std::wstring& _wstErrorFunction)
436 {
437     m_wstErrorFunction = _wstErrorFunction;
438 }
439
440 std::wstring& ConfigVariable::getLastErrorFunction()
441 {
442     return m_wstErrorFunction;
443 }
444
445 /*
446 ** \}
447 */
448
449 /* verbose */
450 bool ConfigVariable::m_bVerbose = true;
451
452 void ConfigVariable::setVerbose(bool _bVerbose)
453 {
454     m_bVerbose = _bVerbose;
455 }
456
457 bool ConfigVariable::getVerbose(void)
458 {
459     return m_bVerbose;
460 }
461
462 /* silent error */
463
464 bool ConfigVariable::m_iSilentError = false;
465
466 void ConfigVariable::setSilentError(bool _iSilentError)
467 {
468     m_iSilentError = _iSilentError;
469 }
470
471 bool ConfigVariable::isSilentError(void)
472 {
473     return m_iSilentError;
474 }
475
476 /* Prompt Mode */
477
478 int ConfigVariable::m_iPromptMode = 0;
479 bool ConfigVariable::m_printInput = true;
480 bool ConfigVariable::m_printOutput = true;
481 bool ConfigVariable::m_printInteractive = false;
482 bool ConfigVariable::m_printCompact = false;
483
484 /*
485 mode        input   output      compact     interactive
486 -----------------------------------------------
487 -1              0       0           0           0
488 0               0       1           1           0
489 1               1       1           1           0
490 2               0       1           0           0
491 3               1       1           0           0
492 4               1       1           1           1
493 7               1       1           0           1
494 */
495
496 void ConfigVariable::setPromptMode(int _iPromptMode)
497 {
498     m_iPromptMode = _iPromptMode;
499     switch (_iPromptMode)
500     {
501         default:
502         case -1:
503             ConfigVariable::setPrintInput(false);
504             ConfigVariable::setPrintOutput(false);
505             ConfigVariable::setPrintCompact(true);
506             ConfigVariable::setPrintInteractive(false);
507             break;
508         case 0:
509             ConfigVariable::setPrintInput(false);
510             ConfigVariable::setPrintOutput(true);
511             ConfigVariable::setPrintCompact(true);
512             ConfigVariable::setPrintInteractive(false);
513             break;
514         case 5:
515         case 1:
516             ConfigVariable::setPrintInput(true);
517             ConfigVariable::setPrintOutput(true);
518             ConfigVariable::setPrintCompact(true);
519             ConfigVariable::setPrintInteractive(false);
520             break;
521         case 2:
522             ConfigVariable::setPrintInput(false);
523             ConfigVariable::setPrintOutput(true);
524             ConfigVariable::setPrintCompact(false);
525             ConfigVariable::setPrintInteractive(false);
526             break;
527         case 3:
528             ConfigVariable::setPrintInput(true);
529             ConfigVariable::setPrintOutput(true);
530             ConfigVariable::setPrintCompact(false);
531             ConfigVariable::setPrintInteractive(false);
532             break;
533         case 4:
534             ConfigVariable::setPrintInput(true);
535             ConfigVariable::setPrintOutput(true);
536             ConfigVariable::setPrintCompact(true);
537             ConfigVariable::setPrintInteractive(true);
538             break;
539         case 6:
540         case 7:
541             ConfigVariable::setPrintInput(true);
542             ConfigVariable::setPrintOutput(true);
543             ConfigVariable::setPrintCompact(false);
544             ConfigVariable::setPrintInteractive(true);
545             break;
546     }
547 }
548
549 int ConfigVariable::getPromptMode(void)
550 {
551     //bool input = isPrintInput();
552     //bool output = isPrintOutput();
553     //bool compact = isPrintCompact();
554     //bool interactive = isPrintInteractive();
555
556     //return !interactive ?
557     //    (/*-1*/ !input && !output ? -1 :
558     //    /* 0*/ !input &&  output &&  compact ? 0 :
559     //    /* 1*/  input &&  output &&  compact ? 1 :
560     //    /* 2*/ !input &&  output && !compact ? 2 :
561     //    /* 3*/  input &&  output && !compact ? 3 : 2 /*default*/) :
562     //    (/* 4*/  compact ? 4 :
563     //    /* 7*/ 7);
564
565     return m_iPromptMode;
566 }
567
568 void ConfigVariable::setPrintInput(bool val)
569 {
570     m_printInput = val;
571 }
572
573 bool ConfigVariable::isPrintInput(void)
574 {
575     return m_printInput;
576 }
577
578 bool ConfigVariable::togglePrintInput(void)
579 {
580     m_printInput = !m_printInput;
581     return m_printInput;
582 }
583
584 void ConfigVariable::setPrintOutput(bool val)
585 {
586     m_printOutput = val;
587 }
588
589 bool ConfigVariable::isPrintOutput(void)
590 {
591     return m_printOutput;
592 }
593
594 bool ConfigVariable::togglePrintOutput(void)
595 {
596     m_printOutput = !m_printOutput;
597     return m_printOutput;
598 }
599
600 void ConfigVariable::setPrintInteractive(bool val)
601 {
602     m_printInteractive = val;
603 }
604
605 bool ConfigVariable::isPrintInteractive(void)
606 {
607     return m_printInteractive;
608 }
609
610 bool ConfigVariable::togglePrintInteractive(void)
611 {
612     m_printInteractive = !m_printInteractive;
613     return m_printInteractive;
614 }
615
616 void ConfigVariable::setPrintCompact(bool val)
617 {
618     m_printCompact = val;
619 }
620
621 bool ConfigVariable::isPrintCompact(void)
622 {
623     return m_printCompact;
624 }
625
626 bool ConfigVariable::togglePrintCompact(void)
627 {
628     m_printCompact = !m_printCompact;
629     return m_printCompact;
630 }
631
632 /*
633 ** \}
634 */
635
636 /*
637 ** Prompt Mode
638 ** \{
639 */
640
641 int ConfigVariable::m_iPauseLevel = 0;
642 std::list<int> ConfigVariable::m_listScope;
643
644 void ConfigVariable::IncreasePauseLevel()
645 {
646     m_iPauseLevel++;
647     m_listScope.push_back(symbol::Context::getInstance()->getScopeLevel());
648 }
649
650 void ConfigVariable::DecreasePauseLevel()
651 {
652     m_iPauseLevel--;
653     m_listScope.pop_back();
654 }
655
656 int ConfigVariable::getActivePauseLevel()
657 {
658     return m_listScope.back();
659 }
660
661 int ConfigVariable::getPauseLevel()
662 {
663     return m_iPauseLevel;
664 }
665
666 /*
667 ** \}
668 */
669
670 /*
671 ** Dynamic Link
672 ** \{
673 */
674
675 std::vector<ConfigVariable::DynamicLibraryStr*> ConfigVariable::m_DynLibList;
676 std::list<ConfigVariable::EntryPointStr*> ConfigVariable::m_EntryPointList;
677
678 ConfigVariable::DynamicLibraryStr* ConfigVariable::getNewDynamicLibraryStr()
679 {
680     DynamicLibraryStr* pDL = (DynamicLibraryStr*)MALLOC(sizeof(DynamicLibraryStr));
681     pDL->pwstLibraryName = NULL;
682     pDL->hLib = 0;
683     return pDL;
684 }
685
686 ConfigVariable::EntryPointStr* ConfigVariable::getNewEntryPointStr()
687 {
688     EntryPointStr* pEP = (EntryPointStr*)MALLOC(sizeof(EntryPointStr));
689     pEP->bOK = false;
690     pEP->functionPtr = NULL;
691     pEP->iLibIndex = -1;
692     pEP->pwstEntryPointName = NULL;
693     return pEP;
694 }
695
696 void ConfigVariable::setLibraryName(ConfigVariable::DynamicLibraryStr* _pDynamicLibrary, wchar_t* _pwstLibraryName)
697 {
698     if (_pDynamicLibrary)
699     {
700         if (_pDynamicLibrary->pwstLibraryName)
701         {
702             FREE(_pDynamicLibrary->pwstLibraryName);
703         }
704         _pDynamicLibrary->pwstLibraryName = os_wcsdup(_pwstLibraryName);
705     }
706 }
707
708 void ConfigVariable::setEntryPointName(ConfigVariable::EntryPointStr* _pEntryPoint, wchar_t* _pwstEntryPointName)
709 {
710     if (_pEntryPoint)
711     {
712         if (_pEntryPoint->pwstEntryPointName)
713         {
714             FREE(_pEntryPoint->pwstEntryPointName);
715         }
716         _pEntryPoint->pwstEntryPointName = os_wcsdup(_pwstEntryPointName);
717     }
718 }
719
720 /* Dynamic libraries functions */
721 int ConfigVariable::addDynamicLibrary(ConfigVariable::DynamicLibraryStr* _pDynamicLibrary)
722 {
723     for (int i = 0; i < (int)m_DynLibList.size(); i++)
724     {
725         if (m_DynLibList[i] == NULL)
726         {
727             m_DynLibList[i] = _pDynamicLibrary;
728             return i;
729         }
730     }
731
732     m_DynLibList.push_back(_pDynamicLibrary);
733     return (int)m_DynLibList.size() - 1;
734 }
735
736 void ConfigVariable::removeDynamicLibrary(int _iDynamicLibraryIndex)
737 {
738     if (_iDynamicLibraryIndex < (int)m_DynLibList.size())
739     {
740         std::list<EntryPointStr*>::const_iterator it;
741         for (it = m_EntryPointList.begin(); it != m_EntryPointList.end();)
742         {
743             //clear all entry points linked to removed dynamic library
744             if ((*it)->iLibIndex == _iDynamicLibraryIndex)
745             {
746                 EntryPointStr* pEP = *it;
747                 m_EntryPointList.remove(*it);
748                 FREE(pEP->pwstEntryPointName);
749                 FREE(pEP);
750                 if (m_EntryPointList.size() == 0)
751                 {
752                     break;
753                 }
754                 it = m_EntryPointList.begin();
755             }
756             else
757             {
758                 ++it;
759             }
760         }
761         //remove dynamic library
762         FREE(m_DynLibList[_iDynamicLibraryIndex]->pwstLibraryName);
763         FREE(m_DynLibList[_iDynamicLibraryIndex]);
764         m_DynLibList[_iDynamicLibraryIndex] = NULL;
765     }
766
767     //clean dynamic library vector
768     while (m_DynLibList.size() != 0 && m_DynLibList.back() == NULL)
769     {
770         m_DynLibList.pop_back();
771     }
772 }
773
774 ConfigVariable::DynamicLibraryStr* ConfigVariable::getDynamicLibrary(int _iDynamicLibraryIndex)
775 {
776     if (_iDynamicLibraryIndex < (int)m_DynLibList.size())
777     {
778         return m_DynLibList[_iDynamicLibraryIndex];
779     }
780     return NULL;
781 }
782
783 bool ConfigVariable::isDynamicLibrary(int _iDynamicLibraryIndex)
784 {
785     if (_iDynamicLibraryIndex < (int)m_DynLibList.size())
786     {
787         if (m_DynLibList[_iDynamicLibraryIndex] != NULL)
788         {
789             return true;
790         }
791     }
792     return false;
793 }
794
795 void ConfigVariable::addEntryPoint(ConfigVariable::EntryPointStr* _pEP)
796 {
797     if (_pEP != NULL)
798     {
799         m_EntryPointList.push_back(_pEP);
800     }
801 }
802
803 ConfigVariable::EntryPointStr* ConfigVariable::getEntryPoint(wchar_t* _pwstEntryPointName, int _iDynamicLibraryIndex)
804 {
805     std::list<EntryPointStr*>::const_iterator it;
806     for (it = m_EntryPointList.begin(); it != m_EntryPointList.end(); it++)
807     {
808         //by pass iLibIndex check if _iDynamicLibraryIndex == -1
809         if (_iDynamicLibraryIndex == -1 || (*it)->iLibIndex == _iDynamicLibraryIndex)
810         {
811             if (wcscmp((*it)->pwstEntryPointName, _pwstEntryPointName) == 0)
812             {
813                 return *it;
814             }
815         }
816     }
817     return NULL;
818 }
819
820 dynlib_ptr ConfigVariable::getEntryPointFromPosition(int position)
821 {
822     std::list<EntryPointStr*>::const_iterator it;
823     int pos = 0;
824     for (it = m_EntryPointList.begin(); it != m_EntryPointList.end(); it++, ++pos)
825     {
826         if (pos == position)
827         {
828             return (*it)->functionPtr;
829         }
830     }
831     return NULL;
832 }
833
834 int ConfigVariable::getEntryPointPosition(wchar_t* _pwstEntryPointName, int _iDynamicLibraryIndex)
835 {
836     int pos = 0;
837     std::list<EntryPointStr*>::const_iterator it;
838     for (it = m_EntryPointList.begin(); it != m_EntryPointList.end(); it++, ++pos)
839     {
840         //by pass iLibIndex check if _iDynamicLibraryIndex == -1
841         if (_iDynamicLibraryIndex == -1 || (*it)->iLibIndex == _iDynamicLibraryIndex)
842         {
843             if (wcscmp((*it)->pwstEntryPointName, _pwstEntryPointName) == 0)
844             {
845                 return pos;
846             }
847         }
848     }
849     return -1;
850 }
851
852 std::vector<std::wstring> ConfigVariable::getEntryPointNameList()
853 {
854     std::vector<std::wstring> EntryPointNames;
855     std::list<EntryPointStr*>::const_iterator it;
856     for (it = m_EntryPointList.begin(); it != m_EntryPointList.end(); it++)
857     {
858         EntryPointNames.push_back((*it)->pwstEntryPointName);
859     }
860     return EntryPointNames;
861 }
862
863 std::vector<ConfigVariable::DynamicLibraryStr*>* ConfigVariable::getDynamicLibraryList()
864 {
865     return &m_DynLibList;
866 }
867
868 std::list<ConfigVariable::EntryPointStr*>* ConfigVariable::getEntryPointList()
869 {
870     return &m_EntryPointList;
871 }
872
873 //dynamic modules
874 std::map<std::wstring, DynLibHandle> ConfigVariable::m_DynModules;
875
876 void ConfigVariable::addDynModule(const std::wstring& _name, DynLibHandle _lib)
877 {
878     m_DynModules[_name] = _lib;
879 }
880
881 void ConfigVariable::removeDynModule(const std::wstring& _name)
882 {
883     m_DynModules.erase(_name);
884 }
885
886 DynLibHandle ConfigVariable::getDynModule(const std::wstring& _name)
887 {
888     std::map<std::wstring, DynLibHandle>::iterator it;
889     it = m_DynModules.find(_name);
890     if (it != m_DynModules.end())
891     {
892         return it->second;
893     }
894
895     return 0;
896 }
897
898 int ConfigVariable::getDynModuleCount()
899 {
900     return (int)m_DynModules.size();
901 }
902
903 DynLibHandle* ConfigVariable::getAllDynModule()
904 {
905     DynLibHandle* moduleList = new DynLibHandle[m_DynModules.size()];
906     std::map<std::wstring, DynLibHandle>::iterator it = m_DynModules.begin();
907     std::map<std::wstring, DynLibHandle>::iterator itEnd = m_DynModules.end();
908     for (int i = 0; it != itEnd; ++it, ++i)
909     {
910         moduleList[i] = it->second;
911     }
912
913     return moduleList;
914 }
915
916 void ConfigVariable::cleanDynModule()
917 {
918     m_DynModules.clear();
919 }
920
921 // Command Line Arguments
922 std::vector<std::wstring> ConfigVariable::m_Args;
923 bool ConfigVariable::m_bTimed = false;
924 bool ConfigVariable::m_bSerialize = false;
925
926 void ConfigVariable::setCommandLineArgs(int _iArgs, char** _pstArgs)
927 {
928     m_Args.clear();
929     for (int i = 0; i < _iArgs; i++)
930     {
931         wchar_t* ws = to_wide_string(_pstArgs[i]);
932         m_Args.push_back(ws);
933         FREE(ws);
934     }
935 }
936
937 wchar_t** ConfigVariable::getCommandLineArgs(int* _piCount)
938 {
939     wchar_t** pwstArgs = NULL;
940     *_piCount = (int)m_Args.size();
941     if (*_piCount != 0)
942     {
943         pwstArgs = (wchar_t**)MALLOC(*_piCount * sizeof(wchar_t*));
944         for (int i = 0; i < *_piCount; i++)
945         {
946             pwstArgs[i] = os_wcsdup(m_Args[i].c_str());
947         }
948     }
949     return pwstArgs;
950 }
951
952 bool ConfigVariable::getTimed()
953 {
954     return m_bTimed;
955 }
956
957 void ConfigVariable::setTimed(bool _bTimed)
958 {
959     m_bTimed = _bTimed;
960 }
961
962 bool ConfigVariable::getSerialize()
963 {
964     return m_bSerialize;
965 }
966
967 void ConfigVariable::setSerialize(bool _bSerialize)
968 {
969     m_bSerialize = _bSerialize;
970 }
971
972 /*
973 ** \}
974 */
975
976 ///*
977 //** Input Method
978 //** \{
979 //*/
980 //
981 //SCILAB_INPUT_METHOD ConfigVariable::m_pInputMethod = NULL;
982 //
983 //void ConfigVariable::setInputMethod(SCILAB_INPUT_METHOD _pInputMethod)
984 //{
985 //    m_pInputMethod = _pInputMethod;
986 //}
987 //
988 //SCILAB_INPUT_METHOD ConfigVariable::getInputMethod(void)
989 //{
990 //    return m_pInputMethod;
991 //}
992 //
993 ///*
994 //** \}
995 //*/
996 //
997 ///*
998 //** Output Method
999 //** \{
1000 //*/
1001 //
1002 //SCILAB_OUTPUT_METHOD ConfigVariable::m_pOutputMethod = NULL;
1003 //
1004 //void ConfigVariable::setOutputMethod(SCILAB_OUTPUT_METHOD _pOutputMethod)
1005 //{
1006 //    m_pOutputMethod = _pOutputMethod;
1007 //}
1008 //
1009 //SCILAB_OUTPUT_METHOD ConfigVariable::getOutputMethod(void)
1010 //{
1011 //    return m_pOutputMethod;
1012 //}
1013 //
1014 ///*
1015 //** \}
1016 //*/
1017
1018 /*
1019 ** schur function
1020 ** \{
1021 */
1022
1023 types::Callable* ConfigVariable::m_schurFunction = NULL;
1024
1025 void ConfigVariable::setSchurFunction(types::Callable* _schurFunction)
1026 {
1027     m_schurFunction = _schurFunction;
1028 }
1029
1030 types::Callable* ConfigVariable::getSchurFunction()
1031 {
1032     return m_schurFunction;
1033 }
1034
1035 /*
1036 ** \}
1037 */
1038
1039 /*
1040 ** grand (module randlib)
1041 ** \{
1042 */
1043
1044 int ConfigVariable::m_currentBaseGen = 0;
1045 int ConfigVariable::m_currentClcg4 = 0;
1046
1047 void ConfigVariable::setCurrentBaseGen(int _gen)
1048 {
1049     m_currentBaseGen = _gen;
1050 }
1051
1052 int ConfigVariable::getCurrentBaseGen()
1053 {
1054     return m_currentBaseGen;
1055 }
1056
1057 void ConfigVariable::setCurrentClcg4(int _clcg4)
1058 {
1059     m_currentClcg4 = _clcg4;
1060 }
1061
1062 int ConfigVariable::getCurrentClcg4()
1063 {
1064     return m_currentClcg4;
1065 }
1066 /*
1067 ** \}
1068 */
1069
1070 /*
1071 ** Start finish flag
1072 ** \{
1073 */
1074 bool ConfigVariable::m_bStartProcessing = false;
1075 bool ConfigVariable::m_bEndProcessing = false;
1076
1077 void ConfigVariable::setStartProcessing(bool _bStartProcessing)
1078 {
1079     m_bStartProcessing = _bStartProcessing;
1080 }
1081
1082 bool ConfigVariable::getStartProcessing()
1083 {
1084     return m_bStartProcessing;
1085 }
1086
1087 void ConfigVariable::setEndProcessing(bool _bEndProcessing)
1088 {
1089     m_bEndProcessing = _bEndProcessing;
1090 }
1091
1092 bool ConfigVariable::getEndProcessing()
1093 {
1094     return m_bEndProcessing;
1095 }
1096 /*
1097 ** \}
1098 */
1099
1100 /*
1101 ** ieee
1102 ** \{
1103 */
1104 int ConfigVariable::m_iIeee = 2;
1105
1106 void ConfigVariable::setIeee(int _iIeee)
1107 {
1108     m_iIeee = _iIeee;
1109 }
1110
1111 int ConfigVariable::getIeee()
1112 {
1113     return m_iIeee;
1114 }
1115 /*
1116 ** \}
1117 */
1118
1119 /*
1120 ** simp Mode
1121 ** \{
1122 */
1123 int ConfigVariable::m_iSimpMode = 1;
1124
1125 void ConfigVariable::setSimpMode(int _iSimpMode)
1126 {
1127     m_iSimpMode = _iSimpMode;
1128 }
1129
1130 int ConfigVariable::getSimpMode()
1131 {
1132     return m_iSimpMode;
1133 }
1134 /*
1135 ** \}
1136 */
1137
1138 /*
1139 ** funcprot Mode
1140 ** \{
1141 */
1142 int ConfigVariable::m_iFuncprot = 1;
1143
1144 void ConfigVariable::setFuncprot(int _iFuncprot)
1145 {
1146     m_iFuncprot = _iFuncprot;
1147 }
1148
1149 int ConfigVariable::getFuncprot()
1150 {
1151     return m_iFuncprot;
1152 }
1153 /*
1154 ** \}
1155 */
1156
1157 /*
1158 ** where
1159 ** \{
1160 */
1161
1162 std::vector<ConfigVariable::WhereEntry> ConfigVariable::m_Where;
1163 std::vector<ConfigVariable::WhereErrorEntry> ConfigVariable::m_WhereError;
1164 std::vector<int> ConfigVariable::m_FirstMacroLine;
1165 void ConfigVariable::where_begin(int _iLineNum, int _iLineLocation, types::Callable* _pCall)
1166 {
1167     const std::wstring* wstrFileName = nullptr;
1168     types::Callable* pCall = _pCall;
1169     if (pCall->isMacroFile())
1170     {
1171         types::Macro* pM = pCall->getAs<types::MacroFile>()->getMacro();
1172         wstrFileName = &pM->getFileName();
1173         pCall = pM;
1174     }
1175     else if (pCall->isMacro())
1176     {
1177         types::Macro* pM = pCall->getAs<types::Macro>();
1178         wstrFileName = &pM->getFileName();
1179     }
1180
1181     m_Where.push_back({_iLineNum, _iLineLocation, symbol::Context::getInstance()->getScopeLevel(), pCall, wstrFileName});
1182 }
1183
1184 void ConfigVariable::where_end()
1185 {
1186     m_Where.pop_back();
1187 }
1188
1189 const std::vector<ConfigVariable::WhereEntry>& ConfigVariable::getWhere()
1190 {
1191     return m_Where;
1192 }
1193
1194 void ConfigVariable::macroFirstLine_begin(int _iLine)
1195 {
1196     m_FirstMacroLine.push_back(_iLine);
1197 }
1198
1199 void ConfigVariable::macroFirstLine_end()
1200 {
1201     m_FirstMacroLine.pop_back();
1202 }
1203
1204 int ConfigVariable::getMacroFirstLines()
1205 {
1206     if (m_FirstMacroLine.empty())
1207     {
1208         return 1;
1209     }
1210
1211     return m_FirstMacroLine.back();
1212 }
1213 void ConfigVariable::setFileNameToLastWhere(const std::wstring* _fileName)
1214 {
1215     m_Where.back().m_file_name = _fileName;
1216 }
1217
1218 void ConfigVariable::whereErrorToString(std::wostringstream& ostr)
1219 {
1220     int iLenName = 1;
1221     bool isExecstr = false;
1222     bool isExecfile = false;
1223
1224     // get max length of functions name and check if exec or execstr have been called.
1225     for (auto& where : m_WhereError)
1226     {
1227         if (isExecstr == false && where.m_function_name == L"execstr")
1228         {
1229             isExecstr = true;
1230             continue;
1231         }
1232         else if (isExecfile == false && where.m_function_name == L"exec")
1233         {
1234             isExecfile = true;
1235             continue;
1236         }
1237
1238         iLenName = std::max((int)where.m_function_name.length(), iLenName);
1239
1240         // in case of bin file, the file path and line is displayed only if the associated .sci file exists
1241         if (where.m_file_name != L"" && where.m_file_name.find(L".bin") != std::wstring::npos)
1242         {
1243             std::size_t pos = where.m_file_name.find_last_of(L".");
1244             where.m_file_name.replace(pos, pos + 4, L".sci");
1245             if (FileExistW(const_cast<wchar_t*>(where.m_file_name.c_str())) == false)
1246             {
1247                 where.m_file_name = L"";
1248             }
1249         }
1250     }
1251
1252     // add margin
1253     iLenName++;
1254
1255     // initialize localized strings
1256     std::wstring wstrBuiltin(_W("in builtin "));
1257     std::wstring wstrAtLine(_W("at line % 5d of function "));
1258     std::wstring wstrExecStr(_W("at line % 5d of executed string "));
1259     std::wstring wstrExecFile(_W("at line % 5d of executed file "));
1260
1261     // compute max size between "at line xxx of function" and "in builtin "
1262     // +1 : line number is pad to 5. length of "% 5d" + 1 == 5
1263     int iMaxLen = std::max(wstrAtLine.length() + 1, wstrBuiltin.length());
1264     if (isExecstr)
1265     {
1266         iMaxLen = std::max(((int)wstrExecStr.length()) + 1, iMaxLen);
1267     }
1268
1269     if (isExecstr)
1270     {
1271         iMaxLen = std::max(((int)wstrExecFile.length()) + 1, iMaxLen);
1272     }
1273
1274     // print call stack
1275     ostr << std::left;
1276     ostr.fill(L' ');
1277     for (auto& where : m_WhereError)
1278     {
1279         ostr.width(iMaxLen);
1280         if (where.m_line == 0)
1281         {
1282             ostr << wstrBuiltin;
1283         }
1284         else
1285         {
1286             if (where.m_function_name == L"execstr")
1287             {
1288                 isExecstr = true;
1289                 wchar_t wcsTmp[bsiz];
1290                 os_swprintf(wcsTmp, bsiz, wstrExecStr.c_str(), where.m_line);
1291                 ostr << wcsTmp << std::endl;
1292                 continue;
1293             }
1294             else if (where.m_function_name == L"exec")
1295             {
1296                 wchar_t wcsTmp[bsiz];
1297                 os_swprintf(wcsTmp, bsiz, wstrExecFile.c_str(), where.m_line);
1298                 ostr << wcsTmp << where.m_file_name << std::endl;
1299                 continue;
1300             }
1301             else
1302             {
1303                 wchar_t wcsTmp[bsiz];
1304                 os_swprintf(wcsTmp, bsiz, wstrAtLine.c_str(), where.m_line);
1305                 ostr << wcsTmp;
1306             }
1307         }
1308
1309         ostr.width(iLenName);
1310         ostr << where.m_function_name;
1311
1312         if (where.m_file_name != L"")
1313         {
1314             // -1 because the first line of a function dec is : "function myfunc()"
1315             ostr << L"( " << where.m_file_name << L" " << _W("line") << L" " << where.m_first_line + where.m_line - 1 << L" )";
1316         }
1317
1318         ostr << std::endl;
1319     }
1320
1321     ostr << std::endl
1322          << std::resetiosflags(std::ios::adjustfield);
1323 }
1324
1325 void ConfigVariable::fillWhereError(int _iErrorLine)
1326 {
1327
1328     if (m_WhereError.empty())
1329     {
1330         int iTmp = 0;
1331         if (_iErrorLine != 0)
1332         {
1333             // +1 because the first line of the funtionDec "function func()" is the line 1.
1334             iTmp = _iErrorLine - getMacroFirstLines() + 1;
1335         }
1336
1337         m_WhereError.reserve(m_Where.size());
1338         for (auto where = m_Where.rbegin(); where != m_Where.rend(); ++where)
1339         {
1340             if (where->m_file_name != nullptr)
1341             {
1342                 m_WhereError.push_back({iTmp, where->m_absolute_line, where->call->getFirstLine(), where->call->getName(), *where->m_file_name});
1343             }
1344             else
1345             {
1346                 m_WhereError.push_back({iTmp, where->m_absolute_line, where->call->getFirstLine(), where->call->getName(), L""});
1347             }
1348
1349             iTmp = where->m_line;
1350         }
1351     }
1352 }
1353
1354 void ConfigVariable::resetWhereError()
1355 {
1356     m_WhereError.clear();
1357 }
1358
1359 /*
1360 ** \}
1361 */
1362
1363 /*
1364 ** module called with variable by reference
1365 ** \{
1366 */
1367
1368 std::list<std::wstring> ConfigVariable::m_ReferenceModules;
1369
1370 bool ConfigVariable::checkReferenceModule(const std::wstring& _module)
1371 {
1372     for (auto ref : m_ReferenceModules)
1373     {
1374         if (ref == _module)
1375         {
1376             return true;
1377         }
1378     }
1379
1380     return false;
1381 }
1382
1383 void ConfigVariable::addReferenceModule(const std::wstring& _module)
1384 {
1385     if (checkReferenceModule(_module) == false)
1386     {
1387         m_ReferenceModules.push_back(_module);
1388     }
1389 }
1390
1391 void ConfigVariable::removeReferenceModule(const std::wstring& _module)
1392 {
1393     if (checkReferenceModule(_module))
1394     {
1395         m_ReferenceModules.remove(_module);
1396     }
1397 }
1398
1399 std::list<std::wstring> ConfigVariable::getReferenceModules()
1400 {
1401     std::list<std::wstring> l(m_ReferenceModules);
1402     return l;
1403 }
1404
1405 /*
1406 ** \}
1407 */
1408
1409 /*
1410 ** analyzer options
1411 ** \{
1412 */
1413
1414 int ConfigVariable::m_analyzerOptions = 0;
1415 void ConfigVariable::setAnalyzerOptions(int _val)
1416 {
1417     m_analyzerOptions = _val;
1418 }
1419
1420 int ConfigVariable::getAnalyzerOptions(void)
1421 {
1422     return m_analyzerOptions;
1423 }
1424
1425 /*
1426 ** \}
1427 */
1428
1429 /*
1430 ** divide by zero
1431 ** \{
1432 */
1433
1434 bool ConfigVariable::m_dividebyzero = false;
1435 void ConfigVariable::setDivideByZero(bool _dividebyzero)
1436 {
1437     m_dividebyzero = _dividebyzero;
1438 }
1439
1440 bool ConfigVariable::isDivideByZero(void)
1441 {
1442     return m_dividebyzero;
1443 }
1444 /*
1445 ** \}
1446 */
1447
1448 //mex info
1449 std::string ConfigVariable::mexFunctionName;
1450 void ConfigVariable::setMexFunctionName(const std::string& name)
1451 {
1452     mexFunctionName = name;
1453 }
1454
1455 std::string& ConfigVariable::getMexFunctionName()
1456 {
1457     return mexFunctionName;
1458 }
1459
1460 /*
1461 ** \}
1462 */
1463 // executed file with exec
1464 int ConfigVariable::m_iFileID = 0;
1465 void ConfigVariable::setExecutedFileID(int _iFileID)
1466 {
1467     m_iFileID = _iFileID;
1468 }
1469
1470 int ConfigVariable::getExecutedFileID()
1471 {
1472     return m_iFileID;
1473 }
1474
1475 /*
1476 ** string read from console by scilabRead
1477 ** \{
1478 */
1479 std::atomic<char*> ConfigVariable::m_pcConsoleReadStr(nullptr);
1480 void ConfigVariable::setConsoleReadStr(char* _pcConsoleReadStr)
1481 {
1482     m_pcConsoleReadStr = _pcConsoleReadStr;
1483 }
1484
1485 char* ConfigVariable::getConsoleReadStr()
1486 {
1487     ThreadManagement::LockScilabRead();
1488     char* tmp = m_pcConsoleReadStr.exchange(NULL);
1489     ThreadManagement::UnlockScilabRead();
1490     return tmp;
1491 }
1492 /*
1493 ** \}
1494 */
1495
1496 /*
1497 ** Tell to the console thread if the scilabRead return
1498 ** is a scilab command or not.
1499 ** \{
1500 */
1501 std::atomic<int> ConfigVariable::m_isScilabCommand(1);
1502 void ConfigVariable::setScilabCommand(int _isciCmd)
1503 {
1504     m_isScilabCommand = _isciCmd;
1505 }
1506
1507 int ConfigVariable::isScilabCommand()
1508 {
1509     return m_isScilabCommand.exchange(1);
1510 }
1511 /*
1512 ** \}
1513 */
1514
1515 //debugger information
1516 bool ConfigVariable::m_bEnabledebug = false;
1517 std::unique_ptr<ast::ConstVisitor> ConfigVariable::m_defaultvisitor(nullptr);
1518
1519 bool ConfigVariable::getEnableDebug()
1520 {
1521     return m_bEnabledebug;
1522 }
1523
1524 void ConfigVariable::setEnableDebug(bool _enable)
1525 {
1526     m_bEnabledebug = _enable;
1527 }
1528
1529 void ConfigVariable::setDefaultVisitor(ast::ConstVisitor* _default)
1530 {
1531     m_defaultvisitor.reset(_default);
1532 }
1533
1534 ast::ConstVisitor* ConfigVariable::getDefaultVisitor()
1535 {
1536     if (m_defaultvisitor.get() == nullptr)
1537     {
1538         m_defaultvisitor.reset(new ast::ExecVisitor());
1539     }
1540     return m_defaultvisitor->clone();
1541 }
1542
1543 bool ConfigVariable::executionbreak = false;
1544
1545 bool ConfigVariable::isExecutionBreak()
1546 {
1547     return executionbreak;
1548 }
1549
1550 void ConfigVariable::setExecutionBreak()
1551 {
1552     executionbreak = true;
1553 }
1554
1555 void ConfigVariable::resetExecutionBreak()
1556 {
1557     executionbreak = false;
1558 }
1559
1560 #ifdef _DEBUG
1561 int ConfigVariable::recursionLimit = 25;
1562 #else
1563 int ConfigVariable::recursionLimit = 1000;
1564 #endif
1565 int ConfigVariable::recursionLevel = 0;
1566
1567 int ConfigVariable::getRecursionLimit()
1568 {
1569     return recursionLimit;
1570 }
1571
1572 int ConfigVariable::setRecursionLimit(int val)
1573 {
1574     int old = recursionLimit;
1575     recursionLimit = std::max(10, val);
1576     return old;
1577 }
1578
1579 int ConfigVariable::getRecursionLevel()
1580 {
1581     return recursionLevel;
1582 }
1583
1584 bool ConfigVariable::increaseRecursion()
1585 {
1586     if (recursionLevel < recursionLimit)
1587     {
1588         ++recursionLevel;
1589         return true;
1590     }
1591
1592     return false;
1593 }
1594
1595 void ConfigVariable::decreaseRecursion()
1596 {
1597     //recursionLevel = std::max(--recursionLevel, 0);
1598     --recursionLevel;
1599 }
1600
1601 void ConfigVariable::resetRecursionLevel()
1602 {
1603     recursionLevel = 0;
1604 }