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