* bug 16280 fixed: allow users to use mode() inside a macro.
[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 /* User Mode */
477
478 int ConfigVariable::m_iUserMode = 0;
479 void ConfigVariable::setUserMode(int _iPromptMode)
480 {
481     m_iUserMode = _iPromptMode;
482     ConfigVariable::setPromptMode(_iPromptMode);
483 }
484
485 int ConfigVariable::getUserMode(void)
486 {
487     return m_iUserMode;
488 }
489
490 /* Prompt Mode */
491
492 int ConfigVariable::m_iPromptMode = 0;
493 bool ConfigVariable::m_printInput = true;
494 bool ConfigVariable::m_printOutput = true;
495 bool ConfigVariable::m_printInteractive = false;
496 bool ConfigVariable::m_printCompact = false;
497
498 /*
499 mode        input   output      compact     interactive
500 -----------------------------------------------
501 -1              0       0           0           0
502 0               0       1           1           0
503 1               1       1           1           0
504 2               0       1           0           0
505 3               1       1           0           0
506 4               1       1           1           1
507 7               1       1           0           1
508 */
509
510 void ConfigVariable::setPromptMode(int _iPromptMode)
511 {
512     m_iPromptMode = _iPromptMode;
513     switch (_iPromptMode)
514     {
515         default:
516         case -1:
517             ConfigVariable::setPrintInput(false);
518             ConfigVariable::setPrintOutput(false);
519             ConfigVariable::setPrintCompact(true);
520             ConfigVariable::setPrintInteractive(false);
521             break;
522         case 0:
523             ConfigVariable::setPrintInput(false);
524             ConfigVariable::setPrintOutput(true);
525             ConfigVariable::setPrintCompact(true);
526             ConfigVariable::setPrintInteractive(false);
527             break;
528         case 5:
529         case 1:
530             ConfigVariable::setPrintInput(true);
531             ConfigVariable::setPrintOutput(true);
532             ConfigVariable::setPrintCompact(true);
533             ConfigVariable::setPrintInteractive(false);
534             break;
535         case 2:
536             ConfigVariable::setPrintInput(false);
537             ConfigVariable::setPrintOutput(true);
538             ConfigVariable::setPrintCompact(false);
539             ConfigVariable::setPrintInteractive(false);
540             break;
541         case 3:
542             ConfigVariable::setPrintInput(true);
543             ConfigVariable::setPrintOutput(true);
544             ConfigVariable::setPrintCompact(false);
545             ConfigVariable::setPrintInteractive(false);
546             break;
547         case 4:
548             ConfigVariable::setPrintInput(true);
549             ConfigVariable::setPrintOutput(true);
550             ConfigVariable::setPrintCompact(true);
551             ConfigVariable::setPrintInteractive(true);
552             break;
553         case 6:
554         case 7:
555             ConfigVariable::setPrintInput(true);
556             ConfigVariable::setPrintOutput(true);
557             ConfigVariable::setPrintCompact(false);
558             ConfigVariable::setPrintInteractive(true);
559             break;
560     }
561 }
562
563 int ConfigVariable::getPromptMode(void)
564 {
565     //bool input = isPrintInput();
566     //bool output = isPrintOutput();
567     //bool compact = isPrintCompact();
568     //bool interactive = isPrintInteractive();
569
570     //return !interactive ?
571     //    (/*-1*/ !input && !output ? -1 :
572     //    /* 0*/ !input &&  output &&  compact ? 0 :
573     //    /* 1*/  input &&  output &&  compact ? 1 :
574     //    /* 2*/ !input &&  output && !compact ? 2 :
575     //    /* 3*/  input &&  output && !compact ? 3 : 2 /*default*/) :
576     //    (/* 4*/  compact ? 4 :
577     //    /* 7*/ 7);
578
579     return m_iPromptMode;
580 }
581
582 void ConfigVariable::setPrintInput(bool val)
583 {
584     m_printInput = val;
585 }
586
587 bool ConfigVariable::isPrintInput(void)
588 {
589     return m_printInput;
590 }
591
592 bool ConfigVariable::togglePrintInput(void)
593 {
594     m_printInput = !m_printInput;
595     return m_printInput;
596 }
597
598 void ConfigVariable::setPrintOutput(bool val)
599 {
600     m_printOutput = val;
601 }
602
603 bool ConfigVariable::isPrintOutput(void)
604 {
605     return m_printOutput;
606 }
607
608 bool ConfigVariable::togglePrintOutput(void)
609 {
610     m_printOutput = !m_printOutput;
611     return m_printOutput;
612 }
613
614 void ConfigVariable::setPrintInteractive(bool val)
615 {
616     m_printInteractive = val;
617 }
618
619 bool ConfigVariable::isPrintInteractive(void)
620 {
621     return m_printInteractive;
622 }
623
624 bool ConfigVariable::togglePrintInteractive(void)
625 {
626     m_printInteractive = !m_printInteractive;
627     return m_printInteractive;
628 }
629
630 void ConfigVariable::setPrintCompact(bool val)
631 {
632     m_printCompact = val;
633 }
634
635 bool ConfigVariable::isPrintCompact(void)
636 {
637     return m_printCompact;
638 }
639
640 bool ConfigVariable::togglePrintCompact(void)
641 {
642     m_printCompact = !m_printCompact;
643     return m_printCompact;
644 }
645
646 /*
647 ** \}
648 */
649
650 /*
651 ** Prompt Mode
652 ** \{
653 */
654
655 int ConfigVariable::m_iPauseLevel = 0;
656 std::list<int> ConfigVariable::m_listScope;
657
658 void ConfigVariable::IncreasePauseLevel()
659 {
660     m_iPauseLevel++;
661     m_listScope.push_back(symbol::Context::getInstance()->getScopeLevel());
662 }
663
664 void ConfigVariable::DecreasePauseLevel()
665 {
666     m_iPauseLevel--;
667     m_listScope.pop_back();
668 }
669
670 int ConfigVariable::getActivePauseLevel()
671 {
672     return m_listScope.back();
673 }
674
675 int ConfigVariable::getPauseLevel()
676 {
677     return m_iPauseLevel;
678 }
679
680 /*
681 ** \}
682 */
683
684 /*
685 ** Dynamic Link
686 ** \{
687 */
688
689 std::vector<ConfigVariable::DynamicLibraryStr*> ConfigVariable::m_DynLibList;
690 std::list<ConfigVariable::EntryPointStr*> ConfigVariable::m_EntryPointList;
691
692 ConfigVariable::DynamicLibraryStr* ConfigVariable::getNewDynamicLibraryStr()
693 {
694     DynamicLibraryStr* pDL = (DynamicLibraryStr*)MALLOC(sizeof(DynamicLibraryStr));
695     pDL->pwstLibraryName = NULL;
696     pDL->hLib = 0;
697     return pDL;
698 }
699
700 ConfigVariable::EntryPointStr* ConfigVariable::getNewEntryPointStr()
701 {
702     EntryPointStr* pEP = (EntryPointStr*)MALLOC(sizeof(EntryPointStr));
703     pEP->bOK = false;
704     pEP->functionPtr = NULL;
705     pEP->iLibIndex = -1;
706     pEP->pwstEntryPointName = NULL;
707     return pEP;
708 }
709
710 void ConfigVariable::setLibraryName(ConfigVariable::DynamicLibraryStr* _pDynamicLibrary, wchar_t* _pwstLibraryName)
711 {
712     if (_pDynamicLibrary)
713     {
714         if (_pDynamicLibrary->pwstLibraryName)
715         {
716             FREE(_pDynamicLibrary->pwstLibraryName);
717         }
718         _pDynamicLibrary->pwstLibraryName = os_wcsdup(_pwstLibraryName);
719     }
720 }
721
722 void ConfigVariable::setEntryPointName(ConfigVariable::EntryPointStr* _pEntryPoint, wchar_t* _pwstEntryPointName)
723 {
724     if (_pEntryPoint)
725     {
726         if (_pEntryPoint->pwstEntryPointName)
727         {
728             FREE(_pEntryPoint->pwstEntryPointName);
729         }
730         _pEntryPoint->pwstEntryPointName = os_wcsdup(_pwstEntryPointName);
731     }
732 }
733
734 /* Dynamic libraries functions */
735 int ConfigVariable::addDynamicLibrary(ConfigVariable::DynamicLibraryStr* _pDynamicLibrary)
736 {
737     for (int i = 0; i < (int)m_DynLibList.size(); i++)
738     {
739         if (m_DynLibList[i] == NULL)
740         {
741             m_DynLibList[i] = _pDynamicLibrary;
742             return i;
743         }
744     }
745
746     m_DynLibList.push_back(_pDynamicLibrary);
747     return (int)m_DynLibList.size() - 1;
748 }
749
750 void ConfigVariable::removeDynamicLibrary(int _iDynamicLibraryIndex)
751 {
752     if (_iDynamicLibraryIndex < (int)m_DynLibList.size())
753     {
754         std::list<EntryPointStr*>::const_iterator it;
755         for (it = m_EntryPointList.begin(); it != m_EntryPointList.end();)
756         {
757             //clear all entry points linked to removed dynamic library
758             if ((*it)->iLibIndex == _iDynamicLibraryIndex)
759             {
760                 EntryPointStr* pEP = *it;
761                 m_EntryPointList.remove(*it);
762                 FREE(pEP->pwstEntryPointName);
763                 FREE(pEP);
764                 if (m_EntryPointList.size() == 0)
765                 {
766                     break;
767                 }
768                 it = m_EntryPointList.begin();
769             }
770             else
771             {
772                 ++it;
773             }
774         }
775         //remove dynamic library
776         FREE(m_DynLibList[_iDynamicLibraryIndex]->pwstLibraryName);
777         FREE(m_DynLibList[_iDynamicLibraryIndex]);
778         m_DynLibList[_iDynamicLibraryIndex] = NULL;
779     }
780
781     //clean dynamic library vector
782     while (m_DynLibList.size() != 0 && m_DynLibList.back() == NULL)
783     {
784         m_DynLibList.pop_back();
785     }
786 }
787
788 ConfigVariable::DynamicLibraryStr* ConfigVariable::getDynamicLibrary(int _iDynamicLibraryIndex)
789 {
790     if (_iDynamicLibraryIndex < (int)m_DynLibList.size())
791     {
792         return m_DynLibList[_iDynamicLibraryIndex];
793     }
794     return NULL;
795 }
796
797 bool ConfigVariable::isDynamicLibrary(int _iDynamicLibraryIndex)
798 {
799     if (_iDynamicLibraryIndex < (int)m_DynLibList.size())
800     {
801         if (m_DynLibList[_iDynamicLibraryIndex] != NULL)
802         {
803             return true;
804         }
805     }
806     return false;
807 }
808
809 void ConfigVariable::addEntryPoint(ConfigVariable::EntryPointStr* _pEP)
810 {
811     if (_pEP != NULL)
812     {
813         m_EntryPointList.push_back(_pEP);
814     }
815 }
816
817 ConfigVariable::EntryPointStr* ConfigVariable::getEntryPoint(wchar_t* _pwstEntryPointName, int _iDynamicLibraryIndex)
818 {
819     std::list<EntryPointStr*>::const_iterator it;
820     for (it = m_EntryPointList.begin(); it != m_EntryPointList.end(); it++)
821     {
822         //by pass iLibIndex check if _iDynamicLibraryIndex == -1
823         if (_iDynamicLibraryIndex == -1 || (*it)->iLibIndex == _iDynamicLibraryIndex)
824         {
825             if (wcscmp((*it)->pwstEntryPointName, _pwstEntryPointName) == 0)
826             {
827                 return *it;
828             }
829         }
830     }
831     return NULL;
832 }
833
834 dynlib_ptr ConfigVariable::getEntryPointFromPosition(int position)
835 {
836     std::list<EntryPointStr*>::const_iterator it;
837     int pos = 0;
838     for (it = m_EntryPointList.begin(); it != m_EntryPointList.end(); it++, ++pos)
839     {
840         if (pos == position)
841         {
842             return (*it)->functionPtr;
843         }
844     }
845     return NULL;
846 }
847
848 int ConfigVariable::getEntryPointPosition(wchar_t* _pwstEntryPointName, int _iDynamicLibraryIndex)
849 {
850     int pos = 0;
851     std::list<EntryPointStr*>::const_iterator it;
852     for (it = m_EntryPointList.begin(); it != m_EntryPointList.end(); it++, ++pos)
853     {
854         //by pass iLibIndex check if _iDynamicLibraryIndex == -1
855         if (_iDynamicLibraryIndex == -1 || (*it)->iLibIndex == _iDynamicLibraryIndex)
856         {
857             if (wcscmp((*it)->pwstEntryPointName, _pwstEntryPointName) == 0)
858             {
859                 return pos;
860             }
861         }
862     }
863     return -1;
864 }
865
866 std::vector<std::wstring> ConfigVariable::getEntryPointNameList()
867 {
868     std::vector<std::wstring> EntryPointNames;
869     std::list<EntryPointStr*>::const_iterator it;
870     for (it = m_EntryPointList.begin(); it != m_EntryPointList.end(); it++)
871     {
872         EntryPointNames.push_back((*it)->pwstEntryPointName);
873     }
874     return EntryPointNames;
875 }
876
877 std::vector<ConfigVariable::DynamicLibraryStr*>* ConfigVariable::getDynamicLibraryList()
878 {
879     return &m_DynLibList;
880 }
881
882 std::list<ConfigVariable::EntryPointStr*>* ConfigVariable::getEntryPointList()
883 {
884     return &m_EntryPointList;
885 }
886
887 //dynamic modules
888 std::map<std::wstring, DynLibHandle> ConfigVariable::m_DynModules;
889
890 void ConfigVariable::addDynModule(const std::wstring& _name, DynLibHandle _lib)
891 {
892     m_DynModules[_name] = _lib;
893 }
894
895 void ConfigVariable::removeDynModule(const std::wstring& _name)
896 {
897     m_DynModules.erase(_name);
898 }
899
900 DynLibHandle ConfigVariable::getDynModule(const std::wstring& _name)
901 {
902     std::map<std::wstring, DynLibHandle>::iterator it;
903     it = m_DynModules.find(_name);
904     if (it != m_DynModules.end())
905     {
906         return it->second;
907     }
908
909     return 0;
910 }
911
912 int ConfigVariable::getDynModuleCount()
913 {
914     return (int)m_DynModules.size();
915 }
916
917 DynLibHandle* ConfigVariable::getAllDynModule()
918 {
919     DynLibHandle* moduleList = new DynLibHandle[m_DynModules.size()];
920     std::map<std::wstring, DynLibHandle>::iterator it = m_DynModules.begin();
921     std::map<std::wstring, DynLibHandle>::iterator itEnd = m_DynModules.end();
922     for (int i = 0; it != itEnd; ++it, ++i)
923     {
924         moduleList[i] = it->second;
925     }
926
927     return moduleList;
928 }
929
930 void ConfigVariable::cleanDynModule()
931 {
932     m_DynModules.clear();
933 }
934
935 // Command Line Arguments
936 std::vector<std::wstring> ConfigVariable::m_Args;
937 bool ConfigVariable::m_bTimed = false;
938 bool ConfigVariable::m_bSerialize = false;
939
940 void ConfigVariable::setCommandLineArgs(int _iArgs, char** _pstArgs)
941 {
942     m_Args.clear();
943     for (int i = 0; i < _iArgs; i++)
944     {
945         wchar_t* ws = to_wide_string(_pstArgs[i]);
946         m_Args.push_back(ws);
947         FREE(ws);
948     }
949 }
950
951 wchar_t** ConfigVariable::getCommandLineArgs(int* _piCount)
952 {
953     wchar_t** pwstArgs = NULL;
954     *_piCount = (int)m_Args.size();
955     if (*_piCount != 0)
956     {
957         pwstArgs = (wchar_t**)MALLOC(*_piCount * sizeof(wchar_t*));
958         for (int i = 0; i < *_piCount; i++)
959         {
960             pwstArgs[i] = os_wcsdup(m_Args[i].c_str());
961         }
962     }
963     return pwstArgs;
964 }
965
966 bool ConfigVariable::getTimed()
967 {
968     return m_bTimed;
969 }
970
971 void ConfigVariable::setTimed(bool _bTimed)
972 {
973     m_bTimed = _bTimed;
974 }
975
976 bool ConfigVariable::getSerialize()
977 {
978     return m_bSerialize;
979 }
980
981 void ConfigVariable::setSerialize(bool _bSerialize)
982 {
983     m_bSerialize = _bSerialize;
984 }
985
986 /*
987 ** \}
988 */
989
990 ///*
991 //** Input Method
992 //** \{
993 //*/
994 //
995 //SCILAB_INPUT_METHOD ConfigVariable::m_pInputMethod = NULL;
996 //
997 //void ConfigVariable::setInputMethod(SCILAB_INPUT_METHOD _pInputMethod)
998 //{
999 //    m_pInputMethod = _pInputMethod;
1000 //}
1001 //
1002 //SCILAB_INPUT_METHOD ConfigVariable::getInputMethod(void)
1003 //{
1004 //    return m_pInputMethod;
1005 //}
1006 //
1007 ///*
1008 //** \}
1009 //*/
1010 //
1011 ///*
1012 //** Output Method
1013 //** \{
1014 //*/
1015 //
1016 //SCILAB_OUTPUT_METHOD ConfigVariable::m_pOutputMethod = NULL;
1017 //
1018 //void ConfigVariable::setOutputMethod(SCILAB_OUTPUT_METHOD _pOutputMethod)
1019 //{
1020 //    m_pOutputMethod = _pOutputMethod;
1021 //}
1022 //
1023 //SCILAB_OUTPUT_METHOD ConfigVariable::getOutputMethod(void)
1024 //{
1025 //    return m_pOutputMethod;
1026 //}
1027 //
1028 ///*
1029 //** \}
1030 //*/
1031
1032 /*
1033 ** schur function
1034 ** \{
1035 */
1036
1037 types::Callable* ConfigVariable::m_schurFunction = NULL;
1038
1039 void ConfigVariable::setSchurFunction(types::Callable* _schurFunction)
1040 {
1041     m_schurFunction = _schurFunction;
1042 }
1043
1044 types::Callable* ConfigVariable::getSchurFunction()
1045 {
1046     return m_schurFunction;
1047 }
1048
1049 /*
1050 ** \}
1051 */
1052
1053 /*
1054 ** grand (module randlib)
1055 ** \{
1056 */
1057
1058 int ConfigVariable::m_currentBaseGen = 0;
1059 int ConfigVariable::m_currentClcg4 = 0;
1060
1061 void ConfigVariable::setCurrentBaseGen(int _gen)
1062 {
1063     m_currentBaseGen = _gen;
1064 }
1065
1066 int ConfigVariable::getCurrentBaseGen()
1067 {
1068     return m_currentBaseGen;
1069 }
1070
1071 void ConfigVariable::setCurrentClcg4(int _clcg4)
1072 {
1073     m_currentClcg4 = _clcg4;
1074 }
1075
1076 int ConfigVariable::getCurrentClcg4()
1077 {
1078     return m_currentClcg4;
1079 }
1080 /*
1081 ** \}
1082 */
1083
1084 /*
1085 ** Start finish flag
1086 ** \{
1087 */
1088 bool ConfigVariable::m_bStartProcessing = false;
1089 bool ConfigVariable::m_bEndProcessing = false;
1090
1091 void ConfigVariable::setStartProcessing(bool _bStartProcessing)
1092 {
1093     m_bStartProcessing = _bStartProcessing;
1094 }
1095
1096 bool ConfigVariable::getStartProcessing()
1097 {
1098     return m_bStartProcessing;
1099 }
1100
1101 void ConfigVariable::setEndProcessing(bool _bEndProcessing)
1102 {
1103     m_bEndProcessing = _bEndProcessing;
1104 }
1105
1106 bool ConfigVariable::getEndProcessing()
1107 {
1108     return m_bEndProcessing;
1109 }
1110 /*
1111 ** \}
1112 */
1113
1114 /*
1115 ** ieee
1116 ** \{
1117 */
1118 int ConfigVariable::m_iIeee = 2;
1119
1120 void ConfigVariable::setIeee(int _iIeee)
1121 {
1122     m_iIeee = _iIeee;
1123 }
1124
1125 int ConfigVariable::getIeee()
1126 {
1127     return m_iIeee;
1128 }
1129 /*
1130 ** \}
1131 */
1132
1133 /*
1134 ** simp Mode
1135 ** \{
1136 */
1137 int ConfigVariable::m_iSimpMode = 1;
1138
1139 void ConfigVariable::setSimpMode(int _iSimpMode)
1140 {
1141     m_iSimpMode = _iSimpMode;
1142 }
1143
1144 int ConfigVariable::getSimpMode()
1145 {
1146     return m_iSimpMode;
1147 }
1148 /*
1149 ** \}
1150 */
1151
1152 /*
1153 ** funcprot Mode
1154 ** \{
1155 */
1156 int ConfigVariable::m_iFuncprot = 1;
1157
1158 void ConfigVariable::setFuncprot(int _iFuncprot)
1159 {
1160     m_iFuncprot = _iFuncprot;
1161 }
1162
1163 int ConfigVariable::getFuncprot()
1164 {
1165     return m_iFuncprot;
1166 }
1167 /*
1168 ** \}
1169 */
1170
1171 /*
1172 ** where
1173 ** \{
1174 */
1175
1176 std::vector<ConfigVariable::WhereEntry> ConfigVariable::m_Where;
1177 std::vector<ConfigVariable::WhereErrorEntry> ConfigVariable::m_WhereError;
1178 std::vector<int> ConfigVariable::m_FirstMacroLine;
1179 void ConfigVariable::where_begin(int _iLineNum, int _iLineLocation, types::Callable* _pCall)
1180 {
1181     const std::wstring* wstrFileName = nullptr;
1182     types::Callable* pCall = _pCall;
1183     if (pCall->isMacroFile())
1184     {
1185         types::Macro* pM = pCall->getAs<types::MacroFile>()->getMacro();
1186         wstrFileName = &pM->getFileName();
1187         pCall = pM;
1188     }
1189     else if (pCall->isMacro())
1190     {
1191         types::Macro* pM = pCall->getAs<types::Macro>();
1192         wstrFileName = &pM->getFileName();
1193     }
1194
1195     m_Where.push_back({_iLineNum, _iLineLocation, symbol::Context::getInstance()->getScopeLevel(), pCall, wstrFileName});
1196 }
1197
1198 void ConfigVariable::where_end()
1199 {
1200     m_Where.pop_back();
1201 }
1202
1203 const std::vector<ConfigVariable::WhereEntry>& ConfigVariable::getWhere()
1204 {
1205     return m_Where;
1206 }
1207
1208 void ConfigVariable::macroFirstLine_begin(int _iLine)
1209 {
1210     m_FirstMacroLine.push_back(_iLine);
1211 }
1212
1213 void ConfigVariable::macroFirstLine_end()
1214 {
1215     m_FirstMacroLine.pop_back();
1216 }
1217
1218 int ConfigVariable::getMacroFirstLines()
1219 {
1220     if (m_FirstMacroLine.empty())
1221     {
1222         return 1;
1223     }
1224
1225     return m_FirstMacroLine.back();
1226 }
1227 void ConfigVariable::setFileNameToLastWhere(const std::wstring* _fileName)
1228 {
1229     m_Where.back().m_file_name = _fileName;
1230 }
1231
1232 void ConfigVariable::whereErrorToString(std::wostringstream& ostr)
1233 {
1234     int iLenName = 1;
1235     bool isExecstr = false;
1236     bool isExecfile = false;
1237
1238     // get max length of functions name and check if exec or execstr have been called.
1239     for (auto& where : m_WhereError)
1240     {
1241         if (isExecstr == false && where.m_function_name == L"execstr")
1242         {
1243             isExecstr = true;
1244             continue;
1245         }
1246         else if (isExecfile == false && where.m_function_name == L"exec")
1247         {
1248             isExecfile = true;
1249             continue;
1250         }
1251
1252         iLenName = std::max((int)where.m_function_name.length(), iLenName);
1253
1254         // in case of bin file, the file path and line is displayed only if the associated .sci file exists
1255         if (where.m_file_name != L"" && where.m_file_name.find(L".bin") != std::wstring::npos)
1256         {
1257             std::size_t pos = where.m_file_name.find_last_of(L".");
1258             where.m_file_name.replace(pos, pos + 4, L".sci");
1259             if (FileExistW(const_cast<wchar_t*>(where.m_file_name.c_str())) == false)
1260             {
1261                 where.m_file_name = L"";
1262             }
1263         }
1264     }
1265
1266     // add margin
1267     iLenName++;
1268
1269     // initialize localized strings
1270     std::wstring wstrBuiltin(_W("in builtin "));
1271     std::wstring wstrAtLine(_W("at line % 5d of function "));
1272     std::wstring wstrExecStr(_W("at line % 5d of executed string "));
1273     std::wstring wstrExecFile(_W("at line % 5d of executed file "));
1274
1275     // compute max size between "at line xxx of function" and "in builtin "
1276     // +1 : line number is pad to 5. length of "% 5d" + 1 == 5
1277     int iMaxLen = std::max(wstrAtLine.length() + 1, wstrBuiltin.length());
1278     if (isExecstr)
1279     {
1280         iMaxLen = std::max(((int)wstrExecStr.length()) + 1, iMaxLen);
1281     }
1282
1283     if (isExecstr)
1284     {
1285         iMaxLen = std::max(((int)wstrExecFile.length()) + 1, iMaxLen);
1286     }
1287
1288     // print call stack
1289     ostr << std::left;
1290     ostr.fill(L' ');
1291     for (auto& where : m_WhereError)
1292     {
1293         ostr.width(iMaxLen);
1294         if (where.m_line == 0)
1295         {
1296             ostr << wstrBuiltin;
1297         }
1298         else
1299         {
1300             if (where.m_function_name == L"execstr")
1301             {
1302                 isExecstr = true;
1303                 wchar_t wcsTmp[bsiz];
1304                 os_swprintf(wcsTmp, bsiz, wstrExecStr.c_str(), where.m_line);
1305                 ostr << wcsTmp << std::endl;
1306                 continue;
1307             }
1308             else if (where.m_function_name == L"exec")
1309             {
1310                 wchar_t wcsTmp[bsiz];
1311                 os_swprintf(wcsTmp, bsiz, wstrExecFile.c_str(), where.m_line);
1312                 ostr << wcsTmp << where.m_file_name << std::endl;
1313                 continue;
1314             }
1315             else
1316             {
1317                 wchar_t wcsTmp[bsiz];
1318                 os_swprintf(wcsTmp, bsiz, wstrAtLine.c_str(), where.m_line);
1319                 ostr << wcsTmp;
1320             }
1321         }
1322
1323         ostr.width(iLenName);
1324         ostr << where.m_function_name;
1325
1326         if (where.m_file_name != L"")
1327         {
1328             // -1 because the first line of a function dec is : "function myfunc()"
1329             ostr << L"( " << where.m_file_name << L" " << _W("line") << L" " << where.m_first_line + where.m_line - 1 << L" )";
1330         }
1331
1332         ostr << std::endl;
1333     }
1334
1335     ostr << std::endl
1336          << std::resetiosflags(std::ios::adjustfield);
1337 }
1338
1339 void ConfigVariable::fillWhereError(int _iErrorLine)
1340 {
1341
1342     if (m_WhereError.empty())
1343     {
1344         int iTmp = 0;
1345         if (_iErrorLine != 0)
1346         {
1347             // +1 because the first line of the funtionDec "function func()" is the line 1.
1348             iTmp = _iErrorLine - getMacroFirstLines() + 1;
1349         }
1350
1351         m_WhereError.reserve(m_Where.size());
1352         for (auto where = m_Where.rbegin(); where != m_Where.rend(); ++where)
1353         {
1354             if (where->m_file_name != nullptr)
1355             {
1356                 m_WhereError.push_back({iTmp, where->m_absolute_line, where->call->getFirstLine(), where->call->getName(), *where->m_file_name});
1357             }
1358             else
1359             {
1360                 m_WhereError.push_back({iTmp, where->m_absolute_line, where->call->getFirstLine(), where->call->getName(), L""});
1361             }
1362
1363             iTmp = where->m_line;
1364         }
1365     }
1366 }
1367
1368 void ConfigVariable::resetWhereError()
1369 {
1370     m_WhereError.clear();
1371 }
1372
1373 /*
1374 ** \}
1375 */
1376
1377 /*
1378 ** module called with variable by reference
1379 ** \{
1380 */
1381
1382 std::list<std::wstring> ConfigVariable::m_ReferenceModules;
1383
1384 bool ConfigVariable::checkReferenceModule(const std::wstring& _module)
1385 {
1386     for (auto ref : m_ReferenceModules)
1387     {
1388         if (ref == _module)
1389         {
1390             return true;
1391         }
1392     }
1393
1394     return false;
1395 }
1396
1397 void ConfigVariable::addReferenceModule(const std::wstring& _module)
1398 {
1399     if (checkReferenceModule(_module) == false)
1400     {
1401         m_ReferenceModules.push_back(_module);
1402     }
1403 }
1404
1405 void ConfigVariable::removeReferenceModule(const std::wstring& _module)
1406 {
1407     if (checkReferenceModule(_module))
1408     {
1409         m_ReferenceModules.remove(_module);
1410     }
1411 }
1412
1413 std::list<std::wstring> ConfigVariable::getReferenceModules()
1414 {
1415     std::list<std::wstring> l(m_ReferenceModules);
1416     return l;
1417 }
1418
1419 /*
1420 ** \}
1421 */
1422
1423 /*
1424 ** analyzer options
1425 ** \{
1426 */
1427
1428 int ConfigVariable::m_analyzerOptions = 0;
1429 void ConfigVariable::setAnalyzerOptions(int _val)
1430 {
1431     m_analyzerOptions = _val;
1432 }
1433
1434 int ConfigVariable::getAnalyzerOptions(void)
1435 {
1436     return m_analyzerOptions;
1437 }
1438
1439 /*
1440 ** \}
1441 */
1442
1443 /*
1444 ** divide by zero
1445 ** \{
1446 */
1447
1448 bool ConfigVariable::m_dividebyzero = false;
1449 void ConfigVariable::setDivideByZero(bool _dividebyzero)
1450 {
1451     m_dividebyzero = _dividebyzero;
1452 }
1453
1454 bool ConfigVariable::isDivideByZero(void)
1455 {
1456     return m_dividebyzero;
1457 }
1458 /*
1459 ** \}
1460 */
1461
1462 //mex info
1463 std::string ConfigVariable::mexFunctionName;
1464 void ConfigVariable::setMexFunctionName(const std::string& name)
1465 {
1466     mexFunctionName = name;
1467 }
1468
1469 std::string& ConfigVariable::getMexFunctionName()
1470 {
1471     return mexFunctionName;
1472 }
1473
1474 /*
1475 ** \}
1476 */
1477 // executed file with exec
1478 int ConfigVariable::m_iFileID = 0;
1479 void ConfigVariable::setExecutedFileID(int _iFileID)
1480 {
1481     m_iFileID = _iFileID;
1482 }
1483
1484 int ConfigVariable::getExecutedFileID()
1485 {
1486     return m_iFileID;
1487 }
1488
1489 /*
1490 ** string read from console by scilabRead
1491 ** \{
1492 */
1493 std::atomic<char*> ConfigVariable::m_pcConsoleReadStr(nullptr);
1494 void ConfigVariable::setConsoleReadStr(char* _pcConsoleReadStr)
1495 {
1496     m_pcConsoleReadStr = _pcConsoleReadStr;
1497 }
1498
1499 char* ConfigVariable::getConsoleReadStr()
1500 {
1501     ThreadManagement::LockScilabRead();
1502     char* tmp = m_pcConsoleReadStr.exchange(NULL);
1503     ThreadManagement::UnlockScilabRead();
1504     return tmp;
1505 }
1506 /*
1507 ** \}
1508 */
1509
1510 /*
1511 ** Tell to the console thread if the scilabRead return
1512 ** is a scilab command or not.
1513 ** \{
1514 */
1515 std::atomic<int> ConfigVariable::m_isScilabCommand(1);
1516 void ConfigVariable::setScilabCommand(int _isciCmd)
1517 {
1518     m_isScilabCommand = _isciCmd;
1519 }
1520
1521 int ConfigVariable::isScilabCommand()
1522 {
1523     return m_isScilabCommand.exchange(1);
1524 }
1525 /*
1526 ** \}
1527 */
1528
1529 //debugger information
1530 bool ConfigVariable::m_bEnabledebug = false;
1531 std::unique_ptr<ast::ConstVisitor> ConfigVariable::m_defaultvisitor(nullptr);
1532
1533 bool ConfigVariable::getEnableDebug()
1534 {
1535     return m_bEnabledebug;
1536 }
1537
1538 void ConfigVariable::setEnableDebug(bool _enable)
1539 {
1540     m_bEnabledebug = _enable;
1541 }
1542
1543 void ConfigVariable::setDefaultVisitor(ast::ConstVisitor* _default)
1544 {
1545     m_defaultvisitor.reset(_default);
1546 }
1547
1548 ast::ConstVisitor* ConfigVariable::getDefaultVisitor()
1549 {
1550     if (m_defaultvisitor.get() == nullptr)
1551     {
1552         m_defaultvisitor.reset(new ast::ExecVisitor());
1553     }
1554     return m_defaultvisitor->clone();
1555 }
1556
1557 bool ConfigVariable::executionbreak = false;
1558
1559 bool ConfigVariable::isExecutionBreak()
1560 {
1561     return executionbreak;
1562 }
1563
1564 void ConfigVariable::setExecutionBreak()
1565 {
1566     executionbreak = true;
1567 }
1568
1569 void ConfigVariable::resetExecutionBreak()
1570 {
1571     executionbreak = false;
1572 }
1573
1574 #ifdef _DEBUG
1575 int ConfigVariable::recursionLimit = 25;
1576 #else
1577 int ConfigVariable::recursionLimit = 1000;
1578 #endif
1579 int ConfigVariable::recursionLevel = 0;
1580
1581 int ConfigVariable::getRecursionLimit()
1582 {
1583     return recursionLimit;
1584 }
1585
1586 int ConfigVariable::setRecursionLimit(int val)
1587 {
1588     int old = recursionLimit;
1589     recursionLimit = std::max(10, val);
1590     return old;
1591 }
1592
1593 int ConfigVariable::getRecursionLevel()
1594 {
1595     return recursionLevel;
1596 }
1597
1598 bool ConfigVariable::increaseRecursion()
1599 {
1600     if (recursionLevel < recursionLimit)
1601     {
1602         ++recursionLevel;
1603         return true;
1604     }
1605
1606     return false;
1607 }
1608
1609 void ConfigVariable::decreaseRecursion()
1610 {
1611     //recursionLevel = std::max(--recursionLevel, 0);
1612     --recursionLevel;
1613 }
1614
1615 void ConfigVariable::resetRecursionLevel()
1616 {
1617     recursionLevel = 0;
1618 }
1619
1620 //webmode
1621 bool ConfigVariable::webMode = true;
1622
1623 bool ConfigVariable::getWebMode()
1624 {
1625     return webMode;
1626 }
1627
1628 void ConfigVariable::setWebMode(bool _mode)
1629 {
1630     webMode = _mode;
1631 }