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