Remove memory leaks
[scilab.git] / scilab / modules / output_stream / src / c / msgstore.c
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) INRIA
4 * Copyright (C) DIGITEO - 2010-2011 - Allan CORNET
5
6 * This file must be used under the terms of the CeCILL.
7 * This source file is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution.  The terms
9 * are also available at    
10 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11 *
12 */
13 #include <string.h>
14 #include <stdlib.h>
15 #include "MALLOC.h"
16 #include "stack-c.h"
17 #include "msgstore.h"
18 #include "lasterror.h"
19 #ifdef _MSC_VER
20 #include "strdup_windows.h"
21 #endif
22 #include "freeArrayOfString.h"
23 #include "strsubst.h"
24 /*--------------------------------------------------------------------------*/
25 static char **splitErrorMessage(const char *msg, int *nbLines);
26 /*--------------------------------------------------------------------------*/
27 int C2F(linestore)(int *n)
28 {
29     setInternalLastErrorLinePosition(*n);
30     return 0;
31 }
32 /*--------------------------------------------------------------------------*/
33 int C2F(funnamestore)(char *str, int *n, int lenstr)
34 {
35     char *functionName = strdup(str);
36     if ( (functionName) && (*n >= 0) )
37     {
38         functionName[*n] = 0;
39         setInternalLastErrorFunctionName(functionName);
40     }
41
42     if (functionName)
43     {
44         FREE(functionName);
45         functionName = NULL;
46     }
47
48     return 0;
49 }
50 /*--------------------------------------------------------------------------*/
51 int C2F(msgstore)(char *str, int *n)
52 {
53     int iRes = 0;
54
55     char **multilines = NULL;
56     int nbLines = 0;
57     int i = 0;
58     char *msg = NULL;
59     char *msgTmp = NULL;
60
61     if (str == NULL) return 1;
62     msg = strdup(str);
63     if (msg)
64     {
65         msg[*n] = 0;
66     }
67
68     // remove duplicate percent bug 9571
69     msgTmp = strsub(msg, "%%", "%");
70     if (msgTmp)
71     {
72         FREE(msg);
73         msg = msgTmp;
74     }
75     multilines = splitErrorMessage(msg, &nbLines);
76     if (multilines)
77     {
78         for (i = 0; i < nbLines; i++)
79         {
80             iRes = appendStringToInternalLastErrorMessage(multilines[i]);
81             if (iRes) break;
82         }
83         freeArrayOfString(multilines, nbLines);
84         multilines = NULL;
85     }
86     else
87     {
88         iRes = appendStringToInternalLastErrorMessage(msg);
89     }
90
91     if (msg)
92     {
93         FREE(msg);
94         msg = NULL;
95     }
96
97     return iRes;
98 }
99 /*--------------------------------------------------------------------------*/
100 int GetLastErrorCode(void)
101 {
102     return getInternalLastErrorValue();
103 }
104 /*--------------------------------------------------------------------------*/
105 static char **splitErrorMessage(const char *msg, int *nbLines)
106 {
107     const char* separator = "\n";
108     int removeEmptyField = 1;
109
110     size_t sizeSeparator = strlen(separator);
111     char** currentSplit  = NULL;
112     size_t nbSep = 0;
113     size_t nbEmptyField = 0;
114     size_t sizeSplit = 0;
115     size_t currentSep = 0;
116     char* pos = NULL;
117     char* currentPos = NULL;
118     char *str = strdup(msg);
119
120     *nbLines = 0;
121
122     if (msg == NULL) 
123     {
124         return NULL;
125     }
126
127     pos = str;
128     currentPos = str;
129
130     while( pos = strstr( pos, separator ) ) 
131     {
132         memset( pos, '\0', sizeSeparator );
133         if ( pos == str || ( pos != str && !*(pos-1) ) )
134         {
135             ++nbEmptyField;
136         }
137         ++nbSep;
138         currentPos = (pos += sizeSeparator);
139     }
140     if ( currentPos == str || ( currentPos != str && !*currentPos ) )
141     {
142         ++nbEmptyField;
143     }
144
145     sizeSplit = (nbSep + 1) - (removeEmptyField?nbEmptyField:0);
146     if (!sizeSplit) 
147     {
148         if (str)
149         {
150             FREE(str);
151             str = NULL;
152         }
153         return NULL;
154     }
155
156     currentSplit = (char **)MALLOC( (sizeSplit) * sizeof(char*) );
157     if (!currentSplit) 
158     {
159         if (str)
160         {
161             FREE(str);
162             str = NULL;
163         }
164         return NULL;
165     }
166     pos = str;
167     while( currentSep < sizeSplit ) 
168     {
169         if ( !( removeEmptyField && !*pos ) )
170         {
171             currentSplit[currentSep++] = strdup(pos);
172         }
173
174         while( *pos++ );
175         pos += sizeSeparator - 1;
176     }
177
178     if (str)
179     {
180         FREE(str);
181         str = NULL;
182     }
183
184     *nbLines = (int)sizeSplit;
185     return currentSplit;
186 }
187 /*--------------------------------------------------------------------------*/