api_scilab: fix memory leak on SciErr structs
[scilab.git] / scilab / modules / api_scilab / src / cpp / api_error.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2009 - DIGITEO - Antoine ELIAS
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  * Please note that piece of code will be rewrited for the Scilab 6 family
12  * However, the API (profile of the functions in the header files) will be
13  * still available and supported in Scilab 6.
14  */
15
16 #include "MALLOC.h"
17 #include <stdio.h>
18 #include "api_scilab.h"
19 #include "sciprint.h"
20 #include "Scierror.h"
21 #ifdef _MSC_VER
22 #include "strdup_windows.h"
23 #endif
24 #include "localization.h"
25 extern "C"
26 {
27 #include "stackinfo.h"
28 #include "mode_exec.h"
29 }
30
31 int addStackSizeError(SciErr* _psciErr, char* _pstCaller, int _iNeeded)
32 {
33     char pstMsg1[bsiz];
34     char pstMsg2[bsiz];
35     char pstMsg3[bsiz];
36     char pstMsg4[bsiz];
37     char pstMsg5[bsiz];
38
39     int Memory_used_for_variables = 0;
40     int Total_Memory_available = 0;
41
42     C2F(getstackinfo)(&Total_Memory_available, &Memory_used_for_variables);
43
44 #ifdef _MSC_VER
45     sprintf_s(pstMsg1, bsiz, "%s\n%s", _pstCaller, _("stack size exceeded!\n"));
46     sprintf_s(pstMsg2, bsiz, _("Use stacksize function to increase it.\n"));
47     sprintf_s(pstMsg3, bsiz, _("Memory used for variables: %d\n"), Memory_used_for_variables);
48     sprintf_s(pstMsg4, bsiz, _("Intermediate memory needed: %d\n"), _iNeeded);
49     sprintf_s(pstMsg5, bsiz, _("Total memory available: %d\n"), Total_Memory_available);
50 #else
51     sprintf(pstMsg1, _("stack size exceeded!\n"));
52     sprintf(pstMsg2, _("Use stacksize function to increase it.\n"));
53     sprintf(pstMsg3, _("Memory used for variables: %d\n"), Memory_used_for_variables);
54     sprintf(pstMsg4, _("Intermediate memory needed: %d\n"), _iNeeded);
55     sprintf(pstMsg5, _("Total memory available: %d\n"), Total_Memory_available);
56 #endif
57
58     strcat(pstMsg1, pstMsg2);
59     strcat(pstMsg1, pstMsg3);
60     strcat(pstMsg1, pstMsg4);
61     strcat(pstMsg1, pstMsg5);
62
63     return addErrorMessage(_psciErr, 17, pstMsg1);
64 }
65
66 int addErrorMessage(SciErr* _psciErr, int _iErr, const char* _pstMsg, ...)
67 {
68     int iRet = 0;
69     char pstMsg[bsiz];
70     va_list ap;
71
72     va_start(ap, _pstMsg);
73 #if defined (vsnprintf) || defined (linux)
74     iRet = vsnprintf(pstMsg, bsiz - 1, _pstMsg, ap );
75 #else
76     iRet = vsprintf(pstMsg, _pstMsg, ap );
77 #endif
78     va_end(ap);
79
80     if (_psciErr->iMsgCount >= MESSAGE_STACK_SIZE)
81     {
82         // no more space, shift error messages
83         for (int i = 1; i < MESSAGE_STACK_SIZE; i++)
84         {
85             strcpy(_psciErr->pstMsg[i - 1], _psciErr->pstMsg[i]);
86         }
87         strcpy(_psciErr->pstMsg[MESSAGE_STACK_SIZE - 1], pstMsg);
88     }
89     else
90     {
91         strcpy(_psciErr->pstMsg[_psciErr->iMsgCount++], pstMsg);
92     }
93
94     _psciErr->iErr = _iErr;
95     return iRet;
96 }
97
98 int printError(SciErr* _psciErr, int _iLastMsg)
99 {
100     int iMode = getExecMode();
101
102     if (_psciErr->iErr == 0)
103     {
104         return 0;
105     }
106
107     SciStoreError(_psciErr->iErr);
108
109     if (iMode == SILENT_EXEC_MODE)
110     {
111         return 0;
112     }
113
114     if (_iLastMsg)
115     {
116         sciprint(_("API Error:\n"));
117         sciprint(_("\tin %s\n"), _psciErr->pstMsg[0]);
118     }
119     else
120     {
121         sciprint(_("API Error:\n"));
122
123         for (int i = _psciErr->iMsgCount - 1 ;  i >= 0 ; i--)
124         {
125             sciprint(_("\tin %s\n"), _psciErr->pstMsg[i]);
126         }
127     }
128     return 0;
129 }
130
131 char* getErrorMessage(SciErr _sciErr)
132 {
133     if (_sciErr.iErr == 0)
134     {
135         return NULL;
136     }
137
138     return _sciErr.pstMsg[0];
139 }
140