Bug 12284 fixed: Completion in console could to a crash (or deadlock)
[scilab.git] / scilab / modules / completion / src / c / completion.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2007 - INRIA - Allan CORNET
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  */
12 #include <string.h>
13 #include <stdlib.h>
14 #include "completion.h"
15 #include "MALLOC.h"
16 #include "getvariablesname.h"
17 #include "commandwords.h"
18 #include "getfunctionslist.h"
19 #include "getmacrosdictionary.h"
20 #include "completion_generic.h"
21 #include "getfilesdictionary.h"
22 #include "getfieldsdictionary.h"
23 #include "getDictionarySetProperties.h"
24 #include "getDictionaryGetProperties.h"
25 #include "toolsdictionary.h"
26 #if _MSC_VER
27 #include "strdup_windows.h"
28 #endif
29 /*--------------------------------------------------------------------------*/
30 char **completionOnDictionary(char **dictionary,int sizedictionary,char *somechars,int *sizearrayreturned);
31 /*--------------------------------------------------------------------------*/
32 char **completion(char *somechars, int *sizeArrayReturned)
33 {
34     char **ListWords = NULL;
35
36     char **dictionary = NULL;
37     int sizedictionary = 0;
38
39     int sizecompletionfunctions = 0;
40     char **completionfunctions = completionOnFunctions(somechars, &sizecompletionfunctions);
41
42     int sizecompletioncommandwords = 0;
43     char **completioncommandwords = completionOnCommandWords(somechars, &sizecompletioncommandwords);
44
45     int sizecompletionmacros = 0;
46     char **completionmacros =  completionOnMacros(somechars, &sizecompletionmacros);
47
48     int sizecompletionvariables = 0;
49     char **completionvariables = completionOnVariables(somechars, &sizecompletionvariables);
50
51     int sizecompletionhandlegraphicsproperties = 0;
52     char **completionhandlegraphicsproperties = completionOnHandleGraphicsProperties(somechars, &sizecompletionhandlegraphicsproperties);
53
54     int sizecompletionfiles = 0;
55     char **completionfiles = completionOnFiles(somechars, &sizecompletionfiles);
56
57     *sizeArrayReturned = 0;
58
59     sizedictionary = sizecompletionfunctions + sizecompletioncommandwords + sizecompletionmacros
60         + sizecompletionvariables + sizecompletionhandlegraphicsproperties + sizecompletionfiles;
61
62
63     if ( (completionfiles) && (sizedictionary == sizecompletionfiles) )
64     {
65         ListWords = completionfiles;
66         *sizeArrayReturned = sizecompletionfiles;
67     }
68     else
69     {
70         if (sizedictionary > 0) dictionary = (char**)MALLOC(sizeof(char*)*sizedictionary);
71
72         if (dictionary)
73         {
74             int i = 0;
75             appendDictionary(&dictionary,&i,&completionfunctions,&sizecompletionfunctions);
76             appendDictionary(&dictionary,&i,&completioncommandwords,&sizecompletioncommandwords);
77             appendDictionary(&dictionary,&i,&completionmacros,&sizecompletionmacros);
78             appendDictionary(&dictionary,&i,&completionvariables,&sizecompletionvariables);
79             appendDictionary(&dictionary,&i,&completionhandlegraphicsproperties,&sizecompletionhandlegraphicsproperties);
80             appendDictionary(&dictionary,&i,&completionfiles,&sizecompletionfiles);
81
82             dictionary = SortDictionary(dictionary,i);
83             dictionary = RemoveDuplicateDictionary(dictionary,&i);
84
85             sizedictionary = i;
86         }
87         ListWords = completionOnDictionary(dictionary,sizedictionary,somechars,sizeArrayReturned);
88         freePointerDictionary(dictionary,sizedictionary);
89     }
90
91     return ListWords;
92 }
93 /*--------------------------------------------------------------------------*/
94 char **completionOnFunctions(char *somechars, int *sizeArrayReturned)
95 {
96     char **ListWords = NULL;
97     char **dictionary = NULL;
98     int sizedictionary = 0;
99
100     dictionary = GetFunctionsList(&sizedictionary);
101
102     if (dictionary)
103     {
104         dictionary = SortDictionary(dictionary,sizedictionary);
105         ListWords = completionOnDictionary(dictionary,sizedictionary,somechars,sizeArrayReturned);
106         freePointerDictionary(dictionary,sizedictionary);
107     }
108     else
109     {
110         *sizeArrayReturned = 0;
111     }
112     return ListWords;
113 }
114 /*--------------------------------------------------------------------------*/
115 char **completionOnCommandWords(char *somechars, int *sizeArrayReturned)
116 {
117     char **ListWords = NULL;
118     char **dictionary = NULL;
119     int sizedictionary = 0;
120
121     dictionary = getcommandkeywords(&sizedictionary);
122
123     if (dictionary)
124     {
125         dictionary = SortDictionary(dictionary,sizedictionary);
126         dictionary = RemoveDuplicateDictionary(dictionary,&sizedictionary);
127         ListWords = completionOnDictionary(dictionary,sizedictionary,somechars,sizeArrayReturned);
128         freePointerDictionary(dictionary,sizedictionary);
129     }
130     else
131     {
132         *sizeArrayReturned = 0;
133     }
134     return ListWords;
135 }
136 /*--------------------------------------------------------------------------*/
137 char **completionOnMacros(char *somechars, int *sizeArrayReturned)
138 {
139     char **ListWords = NULL;
140     char **dictionary = NULL;
141     int sizedictionary = 0;
142
143     dictionary = getmacrosdictionary(&sizedictionary);
144
145     if (dictionary)
146     {
147         dictionary = SortDictionary(dictionary,sizedictionary);
148         dictionary = RemoveDuplicateDictionary(dictionary,&sizedictionary);
149         ListWords = completionOnDictionary(dictionary,sizedictionary,somechars,sizeArrayReturned);
150         freePointerDictionary(dictionary,sizedictionary);
151     }
152     else
153     {
154         *sizeArrayReturned = 0;
155     }
156     return ListWords;
157 }
158 /*--------------------------------------------------------------------------*/
159 char **completionOnVariables(char *somechars, int *sizeArrayReturned)
160 {
161     char **ListWords = NULL;
162     char **dictionary = NULL;
163     int sizedictionary = 0;
164
165     dictionary = getVariablesName(&sizedictionary,TRUE);
166
167     ListWords = completionOnDictionary(dictionary,sizedictionary,somechars,sizeArrayReturned);
168     freePointerDictionary(dictionary,sizedictionary);
169
170     return ListWords;
171 }
172 /*--------------------------------------------------------------------------*/
173 char **completionOnVariablesWithoutMacros(char *somechars, int *sizeArrayReturned)
174 {
175     int i = 0;
176     int j = 0;
177     int nbWordsAlreadyInMacros = 0;
178
179     char **ListWords = NULL;
180     int sizeListWords = 0;
181
182     char **dictionaryVariables = NULL;
183     int sizedictionaryVariables = 0;
184
185     dictionaryVariables = completionOnVariables(somechars,&sizedictionaryVariables);
186
187     if (sizedictionaryVariables)
188     {
189         char **dictionaryMacros = NULL;
190         int sizedictionaryMacros = 0;
191
192         dictionaryMacros = getmacrosdictionary(&sizedictionaryMacros);
193         dictionaryMacros = SortDictionary(dictionaryMacros, sizedictionaryMacros);
194
195         /* Search if we have more than one definition */
196         for ( i = 0; i < sizedictionaryVariables; i++)
197         {
198             for ( j = 0; j < sizedictionaryMacros; j++)
199             {
200                 if ( strcmp(dictionaryVariables[i], dictionaryMacros[j]) == 0 )
201                 {
202                     nbWordsAlreadyInMacros++;
203                 }
204             }
205         }
206
207         if (nbWordsAlreadyInMacros)
208         {
209             sizeListWords = sizedictionaryVariables - nbWordsAlreadyInMacros;
210             if (sizeListWords > 0)
211             {
212                 char **ListWordsTmp = (char**)MALLOC(sizeof(char*) * sizedictionaryVariables);
213                 if (ListWordsTmp)
214                 {
215                     int k = 0;
216
217                     /* do a copy of dictionary of Variables */
218                     for ( i = 0; i < sizedictionaryVariables; i++)
219                     {
220                         ListWordsTmp[i] = strdup(dictionaryVariables[i]);
221                     }
222
223                     for ( i = 0; i < sizedictionaryVariables; i++)
224                     {
225                         for ( j = 0; j < sizedictionaryMacros; j++)
226                         {
227                             if ( strcmp(dictionaryVariables[i],dictionaryMacros[j]) == 0 )
228                             {
229                                 FREE(ListWordsTmp[i]);
230                                 ListWordsTmp[i] = NULL;
231                             }
232                         }
233                     }
234
235                     ListWords = (char**)MALLOC(sizeof(char*)*(sizeListWords+1));
236                     if (ListWords)
237                     {
238                         for ( i = 0; i < sizedictionaryVariables; i++)
239                         {
240                             if (ListWordsTmp[i])
241                             {
242                                 ListWords[k] = strdup(ListWordsTmp[i]);
243                                 if (k <= sizeListWords) k++;
244                             }
245                         }
246                         /* Add a NULL element at the end (to get number of items from JNI) */
247                         ListWords[sizeListWords] = NULL;
248
249                         *sizeArrayReturned = sizeListWords;
250                     }
251                     else
252                     {
253                         ListWords = NULL;
254                         *sizeArrayReturned = 0;
255                     }
256                 }
257                 else
258                 {
259                     ListWords = NULL;
260                     *sizeArrayReturned = 0;
261                 }
262             }
263             else
264             {
265                 ListWords = NULL;
266                 *sizeArrayReturned = 0;
267             }
268         }
269         else
270         {
271             ListWords = dictionaryVariables;
272             *sizeArrayReturned = sizedictionaryVariables;
273         }
274
275         freePointerDictionary(dictionaryMacros, sizedictionaryMacros);
276     }
277     else
278     {
279         ListWords = NULL;
280         *sizeArrayReturned = 0;
281     }
282
283     return ListWords;
284 }
285 /*--------------------------------------------------------------------------*/
286 char **completionOnFiles(char *somechars, int *sizeArrayReturned)
287 {
288     char **ListWords = NULL;
289     char **dictionary = NULL;
290     int sizedictionary = 0;
291
292     dictionary = getfilesdictionary(somechars,&sizedictionary,FALSE);
293
294     if (dictionary)
295     {
296         ListWords = dictionary;
297         *sizeArrayReturned = sizedictionary;
298     }
299     else
300     {
301         *sizeArrayReturned = 0;
302     }
303     return ListWords;
304 }
305 /*--------------------------------------------------------------------------*/
306 char **completionOnFields(char *lineBeforeCaret, char *pattern, int *sizeArrayReturned)
307 {
308     char **ListWords = NULL;
309     char **dictionary = NULL;
310     int sizedictionary = 0;
311
312     if (lineBeforeCaret && pattern)
313     {
314         dictionary = getfieldsdictionary(lineBeforeCaret, pattern, &sizedictionary);
315     }
316
317     if (dictionary)
318     {
319         ListWords = dictionary;
320         *sizeArrayReturned = sizedictionary;
321     }
322     else
323     {
324         *sizeArrayReturned = 0;
325     }
326     return ListWords;
327 }
328 /*--------------------------------------------------------------------------*/
329 char **completionOnHandleGraphicsProperties(char *somechars, int *sizeArrayReturned)
330 {
331     char **ListWords = NULL;
332     char **dictionary = NULL;
333     int sizedictionary = 0;
334
335     int sizeHandleGraphicsGetPropertiesDictionary = 0;
336     char **HandleGraphicsGetPropertiesDictionary = getDictionaryGetProperties(&sizeHandleGraphicsGetPropertiesDictionary);
337
338     int sizeHandleGraphicsSetPropertiesDictionary = 0;
339     char **HandleGraphicsSetPropertiesDictionary = getDictionarySetProperties(&sizeHandleGraphicsSetPropertiesDictionary);
340
341     *sizeArrayReturned = 0;
342
343     sizedictionary = sizeHandleGraphicsGetPropertiesDictionary + sizeHandleGraphicsSetPropertiesDictionary;
344
345     if (sizedictionary > 0)
346     {
347         dictionary = (char**)MALLOC(sizeof(char*)*sizedictionary);
348
349         if (dictionary)
350         {
351             int i = 0;
352
353             appendDictionary(&dictionary,&i,&HandleGraphicsGetPropertiesDictionary,&sizeHandleGraphicsGetPropertiesDictionary);
354             appendDictionary(&dictionary,&i,&HandleGraphicsSetPropertiesDictionary,&sizeHandleGraphicsSetPropertiesDictionary);
355             sizedictionary = i;
356         }
357
358         if (dictionary)
359         {
360             dictionary = SortDictionary(dictionary,sizedictionary);
361             dictionary = RemoveDuplicateDictionary(dictionary,&sizedictionary);
362             ListWords = completionOnDictionary(dictionary,sizedictionary,somechars,sizeArrayReturned);
363             freePointerDictionary(dictionary,sizedictionary);
364         }
365         else
366         {
367             *sizeArrayReturned = 0;
368         }
369     }
370     else
371     {
372         *sizeArrayReturned = 0;
373     }
374     return ListWords;
375 }
376 /*--------------------------------------------------------------------------*/
377 char **completionOnDictionary(char **dictionary,int sizedictionary,char *somechars,int *sizearrayreturned)
378 {
379     char **ListWords = NULL;
380
381     if (dictionary)
382     {
383         ListWords = completion_generic(dictionary,sizedictionary,somechars,sizearrayreturned);
384         if (ListWords == NULL) *sizearrayreturned = 0;
385     }
386     else
387     {
388         *sizearrayreturned = 0;
389     }
390     return ListWords;
391 }
392 /*--------------------------------------------------------------------------*/