0c0e206a7c3652f709cf89d6dafb7f4400056a7e
[scilab.git] / scilab / modules / preferences / src / c / getScilabPreference.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - 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.1-en.txt
10  *
11  */
12
13 /*--------------------------------------------------------------------------*/
14 #include <stdlib.h>
15 #include <libxml/xpath.h>
16 #include <libxml/xmlreader.h>
17 #include "getScilabPreference.h"
18 #include "GetXmlFileEncoding.h"
19 #include "MALLOC.h"
20 #include "FileExist.h"
21 #include "stricmp.h"
22 #ifdef _MSC_VER
23 #include "strdup_windows.h"
24 #endif
25 #include "getshortpathname.h"
26 #include "BOOL.h"
27 #include "SCIHOME.h"
28
29 #define XCONF "%s/XConfiguration.xml"
30
31 /*--------------------------------------------------------------------------*/
32 static unsigned char isInit = 0;
33 static ScilabPreferences scilabPref;
34 static char * emptyAttribute = "";
35 /*--------------------------------------------------------------------------*/
36 static void getPrefs();
37 static char * getAttribute(xmlDocPtr doc, xmlXPathContextPtr xpathCtxt, const char * xpath);
38 static void initPrefs();
39 static void getDocAndCtxt(xmlDocPtr * doc, xmlXPathContextPtr * xpathCtxt);
40 /*--------------------------------------------------------------------------*/
41 const ScilabPreferences * getScilabPreferences()
42 {
43     getPrefs();
44     return &scilabPref;
45 }
46 /*--------------------------------------------------------------------------*/
47 void initPrefs()
48 {
49     scilabPref.heapSize = NULL;
50     scilabPref.adaptToDisplay = NULL;
51     scilabPref.columnsToDisplay = NULL;
52     scilabPref.linesToDisplay = NULL;
53     scilabPref.historySaveAfter = NULL;
54     scilabPref.historyFile = NULL;
55     scilabPref.historyLines = NULL;
56     scilabPref.historyEnable = NULL;
57     scilabPref.ieee = NULL;
58     scilabPref.format = NULL;
59     scilabPref.formatWidth = NULL;
60     scilabPref.language = NULL;
61     scilabPref.startup_dir_use = NULL;
62     scilabPref.startup_dir_default = NULL;
63     scilabPref.startup_dir_previous = NULL;
64 }
65 /*--------------------------------------------------------------------------*/
66 void reloadScilabPreferences()
67 {
68     clearScilabPreferences();
69     getPrefs();
70 }
71 /*--------------------------------------------------------------------------*/
72 void clearScilabPreferences()
73 {
74     if (isInit == 1)
75     {
76         if (scilabPref.heapSize)
77         {
78             FREE((void*)scilabPref.heapSize);
79         }
80         if (scilabPref.adaptToDisplay)
81         {
82             FREE((void*)scilabPref.adaptToDisplay);
83         }
84         if (scilabPref.columnsToDisplay)
85         {
86             FREE((void*)scilabPref.columnsToDisplay);
87         }
88         if (scilabPref.linesToDisplay)
89         {
90             FREE((void*)scilabPref.linesToDisplay);
91         }
92         if (scilabPref.historySaveAfter)
93         {
94             FREE((void*)scilabPref.historySaveAfter);
95         }
96         if (scilabPref.historyFile)
97         {
98             FREE((void*)scilabPref.historyFile);
99         }
100         if (scilabPref.historyLines)
101         {
102             FREE((void*)scilabPref.historyLines);
103         }
104         if (scilabPref.historyEnable)
105         {
106             FREE((void*)scilabPref.historyEnable);
107         }
108         if (scilabPref.ieee)
109         {
110             FREE((void*)scilabPref.ieee);
111         }
112         if (scilabPref.format)
113         {
114             FREE((void*)scilabPref.format);
115         }
116         if (scilabPref.formatWidth)
117         {
118             FREE((void*)scilabPref.formatWidth);
119         }
120         if (scilabPref.language)
121         {
122             FREE((void*)scilabPref.language);
123         }
124         if (scilabPref.startup_dir_use)
125         {
126             FREE((void*)scilabPref.startup_dir_use);
127         }
128         if (scilabPref.startup_dir_default)
129         {
130             FREE((void*)scilabPref.startup_dir_default);
131         }
132         if (scilabPref.startup_dir_previous)
133         {
134             FREE((void*)scilabPref.startup_dir_previous);
135         }
136         initPrefs();
137     }
138     isInit = 0;
139 }
140 /*--------------------------------------------------------------------------*/
141 void getPrefs()
142 {
143     if (!isInit)
144     {
145         xmlDocPtr doc = NULL;
146         xmlXPathContextPtr xpathCtxt = NULL;
147
148         initPrefs();
149
150         getDocAndCtxt(&doc, &xpathCtxt);
151         if (doc == NULL)
152         {
153             return;
154         }
155
156         scilabPref.heapSize = strdup(getAttribute(doc, xpathCtxt, HEAPSIZE_XPATH));
157         scilabPref.adaptToDisplay = strdup(getAttribute(doc, xpathCtxt, ADAPTTODISPLAY_XPATH));
158         scilabPref.columnsToDisplay = strdup(getAttribute(doc, xpathCtxt, COLUMNSTODISPLAY_XPATH));
159         scilabPref.linesToDisplay = strdup(getAttribute(doc, xpathCtxt, LINESTODISPLAY_XPATH));
160         scilabPref.historySaveAfter = strdup(getAttribute(doc, xpathCtxt, HISTORYSAVEAFTER_XPATH));
161         scilabPref.historyFile = strdup(getAttribute(doc, xpathCtxt, HISTORYFILE_XPATH));
162         scilabPref.historyLines = strdup(getAttribute(doc, xpathCtxt, HISTORYLINES_XPATH));
163         scilabPref.historyEnable = strdup(getAttribute(doc, xpathCtxt, HISTORYENABLE_XPATH));
164         scilabPref.ieee = strdup(getAttribute(doc, xpathCtxt, IEEE_XPATH));
165         scilabPref.format = strdup(getAttribute(doc, xpathCtxt, FORMAT_XPATH));
166         scilabPref.formatWidth = strdup(getAttribute(doc, xpathCtxt, FORMATWIDTH_XPATH));
167         scilabPref.language = strdup(getAttribute(doc, xpathCtxt, LANGUAGE_XPATH));
168         scilabPref.startup_dir_use = strdup(getAttribute(doc, xpathCtxt, STARTUP_DIR_USE_XPATH));
169         scilabPref.startup_dir_default = strdup(getAttribute(doc, xpathCtxt, STARTUP_DIR_DEFAULT_XPATH));
170         scilabPref.startup_dir_previous = strdup(getAttribute(doc, xpathCtxt, STARTUP_DIR_PREVIOUS_XPATH));
171
172         xmlXPathFreeContext(xpathCtxt);
173         xmlFreeDoc(doc);
174
175         isInit = 1;
176     }
177 }
178 /*--------------------------------------------------------------------------*/
179 char * getAttribute(xmlDocPtr doc, xmlXPathContextPtr xpathCtxt, const char * xpath)
180 {
181     char * value = emptyAttribute;
182     xmlXPathObjectPtr xpathObj = xmlXPathEval((const xmlChar*)xpath, xpathCtxt);
183     if (xpathObj && xpathObj->nodesetval && xpathObj->nodesetval->nodeMax)
184     {
185         value = (char *)((xmlAttrPtr)xpathObj->nodesetval->nodeTab[0])->children->content;
186     }
187
188     if (xpathObj)
189     {
190         xmlXPathFreeObject(xpathObj);
191     }
192
193     return value;
194 }
195 /*--------------------------------------------------------------------------*/
196 void getDocAndCtxt(xmlDocPtr * doc, xmlXPathContextPtr * xpathCtxt)
197 {
198     char * SCIHOME = NULL;
199     char * path = NULL;
200     BOOL bConvert = FALSE;
201     char * shortfilename_xml_conf = NULL;
202     char * ret = NULL;
203
204     SCIHOME = getSCIHOME();
205     path = (char *)MALLOC(strlen(SCIHOME) + strlen(XCONF));
206
207     sprintf(path, XCONF, SCIHOME);
208     FREE(SCIHOME);
209
210     if (FileExist(path))
211     {
212         shortfilename_xml_conf = getshortpathname(path, &bConvert);
213         if (shortfilename_xml_conf)
214         {
215             *doc = xmlParseFile(shortfilename_xml_conf);
216             FREE(shortfilename_xml_conf);
217             shortfilename_xml_conf = NULL;
218         }
219         FREE(path);
220         path = NULL;
221     }
222
223     if (*doc == NULL)
224     {
225         *xpathCtxt = NULL;
226         return;
227     }
228
229     if (stricmp((*doc)->encoding, "utf-8"))
230     {
231         xmlFreeDoc(*doc);
232         *doc = NULL;
233         *xpathCtxt = NULL;
234         return;
235     }
236
237     *xpathCtxt = xmlXPathNewContext(*doc);
238     if (*xpathCtxt == NULL)
239     {
240         xmlFreeDoc(*doc);
241         *doc = NULL;
242     }
243 }
244 /*--------------------------------------------------------------------------*/
245 char * getPrefAttributeValue(const char * xpath, const char * attribute)
246 {
247     xmlDocPtr doc = NULL;
248     xmlXPathContextPtr xpathCtxt = NULL;
249     char * ret = NULL;
250
251     unsigned int xlen = 0;
252     unsigned int alen = 0;
253     char * query = (char *)MALLOC((xlen + alen + 2 + 1) * sizeof(char));
254
255     if (!xpath || !attribute)
256     {
257         return NULL;
258     }
259
260     xlen = (unsigned int) strlen(xpath);
261     alen = (unsigned int) strlen(attribute);
262
263     getDocAndCtxt(&doc, &xpathCtxt);
264     if (doc == NULL)
265     {
266         return NULL;
267     }
268
269     if (query)
270     {
271         sprintf(query, "%s/@%s", xpath, attribute);
272         query[xlen + alen + 2] = '\0';
273
274         ret = strdup(getAttribute(doc, xpathCtxt, (const xmlChar*)query));
275         FREE(query);
276     }
277
278     xmlXPathFreeContext(xpathCtxt);
279     xmlFreeDoc(doc);
280
281     return ret;
282 }
283 /*--------------------------------------------------------------------------*/
284 char ** getPrefAttributesValues(const char * xpath, const char ** attributes, const unsigned int attrLen)
285 {
286     xmlDocPtr doc = NULL;
287     xmlXPathContextPtr xpathCtxt = NULL;
288     xmlXPathObjectPtr xpathObj = NULL;
289     char ** ret = NULL;
290
291     if (!xpath || !attributes || !attrLen)
292     {
293         return NULL;
294     }
295
296     getDocAndCtxt(&doc, &xpathCtxt);
297     if (doc == NULL)
298     {
299         return NULL;
300     }
301
302     ret = (char**)MALLOC(sizeof(char*) * attrLen);
303     xpathObj = xmlXPathEval((const xmlChar*)xpath, xpathCtxt);
304     if (xpathObj && xpathObj->nodesetval && xpathObj->nodesetval->nodeMax)
305     {
306         int i;
307         xmlNode * node = (xmlNode*)xpathObj->nodesetval->nodeTab[0];
308         for (i = 0; i < (int)attrLen; i++)
309         {
310             xmlAttr * attrs = xmlHasProp(node, (const xmlChar *)attributes[i]);
311             if (attrs)
312             {
313                 ret[i] = strdup((const char *)attrs->children->content);
314             }
315             else
316             {
317                 int j;
318                 for (j = 0; j < i; j++)
319                 {
320                     free(ret[j]);
321                 }
322                 FREE(ret);
323                 ret = NULL;
324                 break;
325             }
326         }
327     }
328
329     if (xpathObj)
330     {
331         xmlXPathFreeObject(xpathObj);
332     }
333
334     xmlXPathFreeContext(xpathCtxt);
335     xmlFreeDoc(doc);
336
337     return ret;
338 }
339 /*--------------------------------------------------------------------------*/
340 void setPrefAttributesValues(const char * xpath, const char ** kv, const unsigned int kvLen)
341 {
342     xmlDocPtr doc = NULL;
343     xmlXPathContextPtr xpathCtxt = NULL;
344     xmlXPathObjectPtr xpathObj = NULL;
345     char * SCIHOME = NULL;
346     char * path = NULL;
347     BOOL bConvert = FALSE;
348     char * shortfilename_xml_conf = NULL;
349
350     if (!xpath || !kv || !kvLen)
351     {
352         return;
353     }
354
355     getDocAndCtxt(&doc, &xpathCtxt);
356     if (doc == NULL)
357     {
358         return;
359     }
360
361     xpathObj = xmlXPathEval((const xmlChar*)xpath, xpathCtxt);
362     if (xpathObj && xpathObj->nodesetval && xpathObj->nodesetval->nodeMax)
363     {
364         int i;
365         xmlNode * node = (xmlNode*)xpathObj->nodesetval->nodeTab[0];
366         for (i = 0; i < (int)kvLen / 2; i++)
367         {
368             xmlAttr * attrs = xmlHasProp(node, (const xmlChar *)kv[2 * i]);
369             if (attrs)
370             {
371                 attrs->children->content = xmlStrdup((const xmlChar *)kv[2 * i + 1]);
372             }
373             else
374             {
375                 break;
376             }
377         }
378     }
379
380     if (xpathObj)
381     {
382         xmlXPathFreeObject(xpathObj);
383     }
384
385     xmlXPathFreeContext(xpathCtxt);
386
387     // Save
388     xmlThrDefIndentTreeOutput(1);
389
390     SCIHOME = getSCIHOME();
391     path = (char *)MALLOC(strlen(SCIHOME) + strlen(XCONF));
392
393     sprintf(path, XCONF, SCIHOME);
394     FREE(SCIHOME);
395
396     if (FileExist(path))
397     {
398         shortfilename_xml_conf = getshortpathname(path, &bConvert);
399         if (shortfilename_xml_conf)
400         {
401             xmlSaveFormatFile(shortfilename_xml_conf, doc, 2);
402             FREE(shortfilename_xml_conf);
403             shortfilename_xml_conf = NULL;
404         }
405         FREE(path);
406         path = NULL;
407     }
408
409     xmlFreeDoc(doc);
410 }