Coverity: Core module errors fixed
[scilab.git] / scilab / modules / core / src / c / getmodules.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2006 - INRIA - Allan CORNET
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 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <libxml/xpath.h>
19 #include <libxml/xmlreader.h>
20 #include "getmodules.h"
21 #include "sci_malloc.h"
22 #include "sci_path.h"
23 #include "localization.h"
24 #include "string.h"
25 #include "sciprint.h"
26 #include "GetXmlFileEncoding.h"
27 #include "scilabDefaults.h"
28 #include "FileExist.h"
29 #include "os_string.h"
30 #include "getshortpathname.h"
31 /*--------------------------------------------------------------------------*/
32 static struct MODULESLIST *ScilabModules = NULL;
33 /*--------------------------------------------------------------------------*/
34 static BOOL ReadModulesFile(void);
35 static BOOL AppendModules(char *filename);
36 static BOOL VerifyModule(char *ModuleName);
37 /*--------------------------------------------------------------------------*/
38 struct MODULESLIST *getmodules(void)
39 {
40     if (ScilabModules == NULL)
41     {
42         ScilabModules = (struct MODULESLIST *)MALLOC(sizeof(struct MODULESLIST));
43         ReadModulesFile();
44     }
45     return ScilabModules;
46 }
47 /*--------------------------------------------------------------------------*/
48 BOOL DisposeModulesInfo(void)
49 {
50     BOOL bOK = FALSE;
51     if (ScilabModules)
52     {
53         int i = 0;
54         for (i = 0; i < ScilabModules->numberofModules; i++)
55         {
56             if (ScilabModules->ModuleList[i])
57             {
58                 FREE(ScilabModules->ModuleList[i]);
59                 ScilabModules->ModuleList[i] = NULL;
60             }
61         }
62         if (ScilabModules->ModuleList)
63         {
64             FREE(ScilabModules->ModuleList);
65             ScilabModules->ModuleList = NULL;
66         }
67         ScilabModules->numberofModules = 0;
68         FREE(ScilabModules);
69         ScilabModules = NULL;
70     }
71
72     return bOK;
73 }
74 /*--------------------------------------------------------------------------*/
75 static BOOL ReadModulesFile(void)
76 {
77     BOOL bOK = FALSE;
78     char *ModulesFilename = NULL;
79     char *SciPath = NULL;
80
81     SciPath = getSCI();
82     if (SciPath == NULL)
83     {
84         sciprint(_("The SCI environment variable is not set.\n"));
85         return FALSE;
86     }
87
88     ModulesFilename = (char*)MALLOC((strlen(SciPath) + strlen("/") + strlen(basenamemodulesfile) + 1) * sizeof(char));
89     sprintf(ModulesFilename, "%s/%s", SciPath, basenamemodulesfile);
90     FREE(SciPath);
91     SciPath = NULL;
92
93     if (FileExist(ModulesFilename))
94     {
95         AppendModules(ModulesFilename);
96         FREE(ModulesFilename);
97         ModulesFilename = NULL;
98     }
99     else
100     {
101         sciprint(_("Cannot load the module declaration file: %s.\n"), ModulesFilename);
102         FREE(ModulesFilename);
103         ModulesFilename = NULL;
104         return FALSE;
105     }
106     return bOK;
107 }
108 /*--------------------------------------------------------------------------*/
109 static BOOL VerifyModule(char *ModuleName)
110 {
111     BOOL bOK = TRUE;
112     char *SciPath = NULL;
113     char *FullPathModuleName = NULL;
114
115
116     SciPath = getSCI();
117     if (SciPath == NULL)
118     {
119         sciprint(_("The SCI environment variable is not set.\n"));
120         return FALSE;
121     }
122
123     FullPathModuleName = (char*)MALLOC((strlen(SciPath) + strlen("%s/modules/%s/etc/%s.start") + (strlen(ModuleName) * 2) + 1) * sizeof(char));
124     sprintf(FullPathModuleName, "%s/modules/%s/etc/%s.start", SciPath, ModuleName, ModuleName);
125     FREE(SciPath);
126     SciPath = NULL;
127
128     /* @TODO add more checks (missing files for example) */
129
130     if (!FileExist(FullPathModuleName))
131     {
132         fprintf(stderr, _("Warning: Could not find %s\n"), FullPathModuleName);
133         bOK = FALSE;
134     }
135     FREE(FullPathModuleName);
136     FullPathModuleName = NULL;
137
138     return bOK;
139 }
140 /*--------------------------------------------------------------------------*/
141 static BOOL AppendModules(char *xmlfilename)
142 {
143     BOOL bOK = FALSE;
144     if ( FileExist(xmlfilename) )
145     {
146         char *encoding = GetXmlFileEncoding(xmlfilename);
147
148         /* Don't care about line return / empty line */
149         xmlKeepBlanksDefault(0);
150         /* check if the XML file has been encoded with utf8 (unicode) or not */
151         if (stricmp("utf-8", encoding) == 0)
152         {
153             xmlDocPtr doc = NULL;
154             xmlXPathContextPtr xpathCtxt = NULL;
155             xmlXPathObjectPtr xpathObj = NULL;
156             char *name = NULL;
157             int activate = 0;
158
159             int indice = 0;
160             BOOL bConvert = FALSE;
161             char *shortxmlfilename = getshortpathname(xmlfilename, &bConvert);
162
163             if (shortxmlfilename)
164             {
165                 doc = xmlParseFile (shortxmlfilename);
166                 FREE(shortxmlfilename);
167                 shortxmlfilename = NULL;
168             }
169
170             if (doc == NULL)
171             {
172                 printf(_("Error: Could not parse file %s.\n"), xmlfilename);
173                 FREE(encoding);
174                 encoding = NULL;
175                 return bOK;
176             }
177
178             xpathCtxt = xmlXPathNewContext(doc);
179             xpathObj = xmlXPathEval((const xmlChar*)"//modules/module", xpathCtxt);
180
181             if (xpathObj && xpathObj->nodesetval->nodeMax)
182             {
183                 /* the Xpath has been understood and there are node */
184                 int    i;
185                 for (i = 0; i < xpathObj->nodesetval->nodeNr; i++)
186                 {
187
188                     xmlAttrPtr attrib = xpathObj->nodesetval->nodeTab[i]->properties;
189                     /* Get the properties of <module>  */
190                     while (attrib != NULL)
191                     {
192                         /* loop until when have read all the attributes */
193                         if (xmlStrEqual (attrib->name, (const xmlChar*) "name"))
194                         {
195                             /* we found the tag name */
196                             const char *str = (const char*)attrib->children->content;
197                             if (name)
198                             {
199                                 FREE(name);
200                             }
201                             name = os_strdup(str);
202                         }
203                         else if (xmlStrEqual (attrib->name, (const xmlChar*) "activate"))
204                         {
205                             /* we found the tag activate */
206                             const char *str = (const char*)attrib->children->content;
207                             if (stricmp(str, "yes") == 0 || strcmp(str, "1") == 0)
208                             {
209                                 activate = 1;
210                             }
211                         }
212                         attrib = attrib->next;
213                     }
214
215                     if ( (name) && (strlen(name) > 0) && (activate) )
216                     {
217                         if ( VerifyModule(name) )
218                         {
219                             if (indice == 0)
220                             {
221                                 ScilabModules->ModuleList = (char**)MALLOC(sizeof(char*) * (indice + 1));
222                             }
223                             else
224                             {
225                                 ScilabModules->ModuleList = (char**)REALLOC(ScilabModules->ModuleList, sizeof(char*) * (indice + 1));
226                             }
227
228                             ScilabModules->numberofModules = indice + 1;
229
230                             ScilabModules->ModuleList[indice] = os_strdup(name);
231                             indice++;
232                         }
233                         else
234                         {
235                             sciprint(_("%s module not found.\n"), name);
236                         }
237                     }
238                     if (name)
239                     {
240                         FREE(name);
241                         name = NULL;
242                     }
243                     activate = 0;
244                 }
245                 bOK = TRUE;
246             }
247
248             if (xpathObj)
249             {
250                 xmlXPathFreeObject(xpathObj);
251             }
252             if (xpathCtxt)
253             {
254                 xmlXPathFreeContext(xpathCtxt);
255             }
256             xmlFreeDoc (doc);
257
258         }
259         else
260         {
261             printf(_("Error: Not a valid module file %s (encoding not '%s') Encoding '%s' found.\n"), xmlfilename, "utf-8", encoding);
262         }
263         FREE(encoding);
264         encoding = NULL;
265     }
266     return bOK;
267 }
268 /*--------------------------------------------------------------------------*/