Coverity: completion module resource leaks fixed
[scilab.git] / scilab / modules / completion / sci_gateway / cpp / sci_completion.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2013 - Scilab Enterprises - Cedric Delamarre
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 "completion_gw.hxx"
17 #include "function.hxx"
18 #include "string.hxx"
19 #include "double.hxx"
20
21 extern "C"
22 {
23 #include "sci_malloc.h"
24 #include "localization.h"
25 #include "completion.h"
26 #include "Scierror.h"
27 #include "toolsdictionary.h"
28 }
29 /*--------------------------------------------------------------------------*/
30 static types::InternalType* doCompletion(const char* _pcSomechars, char** (*pvFunction)(const char*, int*));
31 /*--------------------------------------------------------------------------*/
32 types::Function::ReturnValue sci_completion(types::typed_list &in, int _iRetCount, types::typed_list &out)
33 {
34     types::String* pStrSomechars = NULL;
35     char* pcSomechars = NULL;
36
37     if (in.size() < 1 || in.size() > 2)
38     {
39         Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected."), "completion", 1, 2);
40         return types::Function::Error;
41     }
42
43     if (_iRetCount > 6)
44     {
45         Scierror(78, _("%s: Wrong number of output argument(s): %d to %d expected."), "completion", 1, 6);
46         return types::Function::Error;
47     }
48
49     if (in[0]->isString() == false)
50     {
51         Scierror(999, _("%s: Wrong type for input argument #%d: String expected.\n"), "completion", 1);
52         return types::Function::Error;
53     }
54
55     pStrSomechars = in[0]->getAs<types::String>();
56
57     if (pStrSomechars->isScalar() == false)
58     {
59         Scierror(999, _("%s: Wrong size for input argument #%d: string expected.\n"), "completion", 1);
60         return types::Function::Error;
61     }
62
63     pcSomechars = wide_string_to_UTF8(pStrSomechars->get(0));
64
65     if (in.size() == 1)
66     {
67         if (_iRetCount == 1)
68         {
69             out.push_back(doCompletion(pcSomechars, &completion));
70         }
71         else
72         {
73             out.resize(_iRetCount);
74             switch (_iRetCount)
75             {
76                 case 6 :
77                     out[5] = doCompletion(pcSomechars, &completionOnFiles);
78                 case 5 :
79                     out[4] = doCompletion(pcSomechars, &completionOnHandleGraphicsProperties);
80                 case 4 :
81                     out[3] = doCompletion(pcSomechars, &completionOnMacros);
82                 case 3 :
83                     out[2] = doCompletion(pcSomechars, &completionOnVariables);
84                 case 2 :
85                     out[1] = doCompletion(pcSomechars, &completionOnCommandWords);
86                 default :
87                     out[0] = doCompletion(pcSomechars, &completionOnFunctions);
88             }
89         }
90     }
91     else // if(in.size() == 2)
92     {
93         if (_iRetCount != 1)
94         {
95             Scierror(78, _("%s: Wrong number of output argument(s): %d expected."), "completion", 1);
96             FREE(pcSomechars);
97             return types::Function::Error;
98         }
99
100         if (in[1]->isString() == false)
101         {
102             Scierror(999, _("%s: Wrong type for input argument #%d: String expected.\n"), "completion", 2);
103             FREE(pcSomechars);
104             return types::Function::Error;
105         }
106
107         types::String* pStrDictionary = in[1]->getAs<types::String>();
108
109         if (pStrDictionary->isScalar() == false)
110         {
111             Scierror(999, _("%s: Wrong size for input argument #%d: string expected.\n"), "completion", 2);
112             FREE(pcSomechars);
113             return types::Function::Error;
114         }
115
116         wchar_t* wcsDictionary = pStrDictionary->get(0);
117         if ( wcscmp(wcsDictionary, L"functions") == 0 )
118         {
119             out.push_back(doCompletion(pcSomechars, &completionOnFunctions));
120         }
121         else if ( wcscmp(wcsDictionary, L"commands") == 0 )
122         {
123             out.push_back(doCompletion(pcSomechars, &completionOnCommandWords));
124         }
125         else if ( wcscmp(wcsDictionary, L"variables") == 0 )
126         {
127             out.push_back(doCompletion(pcSomechars, &completionOnVariables));
128         }
129         else if ( wcscmp(wcsDictionary, L"macros") == 0 )
130         {
131             out.push_back(doCompletion(pcSomechars, &completionOnMacros));
132         }
133         else if ( wcscmp(wcsDictionary, L"graphic_properties") == 0 )
134         {
135             out.push_back(doCompletion(pcSomechars, &completionOnHandleGraphicsProperties));
136         }
137         else if ( wcscmp(wcsDictionary, L"files") == 0 )
138         {
139             out.push_back(doCompletion(pcSomechars, &completionOnFiles));
140         }
141         else
142         {
143             Scierror(999, _("%s: Wrong value for input argument: '%s', '%s', '%s', '%s', '%s' or '%s' expected.\n"),
144                      "completion", "functions", "commands", "variables", "macros", "graphic_properties", "files");
145             FREE(pcSomechars);
146             return types::Function::Error;
147         }
148     }
149
150     FREE(pcSomechars);
151     return types::Function::OK;
152 }
153 /*--------------------------------------------------------------------------*/
154 static types::InternalType* doCompletion(const char* _pcSomechars, char** (*pvFunction)(const char*, int*))
155 {
156     char** pstrResults  = NULL;
157     int iSizeResults    = 0;
158
159     pstrResults = (*pvFunction)(_pcSomechars, &iSizeResults);
160
161     if (iSizeResults)
162     {
163         types::String* pStrOut = new types::String(iSizeResults, 1);
164         pStrOut->set(pstrResults);
165         freePointerDictionary(pstrResults, iSizeResults);
166         return pStrOut;
167     }
168     else
169     {
170         return types::Double::Empty();
171     }
172 }
173 /*--------------------------------------------------------------------------*/