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