Bug 12909 fixed: Completion on (mt)list led to a crash
[scilab.git] / scilab / modules / completion / src / cpp / StructFieldsGetter.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2013 - Scilab Enterprises - Calixte DENIZET
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
13 #include "FieldsManager.hxx"
14 #include "StructFieldsGetter.hxx"
15
16 extern "C"
17 {
18 #include "freeArrayOfString.h"
19 #include "api_scilab.h"
20 #include "MALLOC.h"
21 }
22
23 namespace org_modules_completion
24 {
25
26 const char ** StructFieldsGetter::getFieldsName(const std::string & typeName, int * mlist, char ** fieldPath, const int fieldPathLen, int * fieldsSize) const
27 {
28     return getFieldsName(mlist, fieldPath + 1, fieldPathLen - 1, fieldsSize);
29 }
30
31 const char ** StructFieldsGetter::getFieldsName(int * mlist, char ** fieldPath, const int fieldPathLen, int * fieldsSize)
32 {
33     int rows;
34     int cols;
35     int rc;
36     int * piLen = 0;
37     char ** pstData = 0;
38     int nbItem;
39     int * fieldsAddr = 0;
40     SciErr sciErr;
41     const char ** fields = 0;
42
43     *fieldsSize = 0;
44
45     sciErr = getListItemNumber(pvApiCtx, mlist, &nbItem);
46     if (sciErr.iErr)
47     {
48         return 0;
49     }
50
51     if (nbItem == 0)
52     {
53         return 0;
54     }
55
56     sciErr = getListItemAddress(pvApiCtx, mlist, 1, &fieldsAddr);
57     if (sciErr.iErr)
58     {
59         return 0;
60     }
61
62     if (getAllocatedMatrixOfString(pvApiCtx, fieldsAddr, &rows, &cols, &pstData))
63     {
64         return 0;
65     }
66
67     rc = rows * cols;
68     if (rc == 1 || rc == 2)
69     {
70         freeArrayOfString(pstData, rc);
71         return 0;
72     }
73
74     if (fieldPathLen == 0)
75     {
76         *fieldsSize = rc - 2;
77         fields = (const char **)MALLOC(sizeof(char *) **fieldsSize);
78         memcpy(fields, pstData + 2, sizeof(char *) **fieldsSize);
79         FREE(pstData[0]);
80         FREE(pstData[1]);
81         FREE(pstData);
82
83         return fields;
84     }
85
86     for (int i = 2; i < rc; i++)
87     {
88         if (!strcmp(pstData[i], fieldPath[0]))
89         {
90             freeArrayOfString(pstData, rc);
91             int * itemAddr = 0;
92             sciErr = getListItemAddress(pvApiCtx, mlist, i + 1, &itemAddr);
93             if (sciErr.iErr)
94             {
95                 return 0;
96             }
97
98             return FieldsManager::getFields(itemAddr, fieldPath, fieldPathLen, fieldsSize);
99         }
100     }
101
102     freeArrayOfString(pstData, rc);
103
104     return 0;
105 }
106 }