20cc95590a08ef4a5d7eb81a4ce311b9cf2c46dd
[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     }
220
221     FREE(path);
222     path = NULL;
223
224     if (*doc == NULL)
225     {
226         *xpathCtxt = NULL;
227         return;
228     }
229
230     if (stricmp((*doc)->encoding, "utf-8"))
231     {
232         xmlFreeDoc(*doc);
233         *doc = NULL;
234         *xpathCtxt = NULL;
235         return;
236     }
237
238     *xpathCtxt = xmlXPathNewContext(*doc);
239     if (*xpathCtxt == NULL)
240     {
241         xmlFreeDoc(*doc);
242         *doc = NULL;
243     }
244 }
245 /*--------------------------------------------------------------------------*/
246 char * getPrefAttributeValue(const char * xpath, const char * attribute)
247 {
248     xmlDocPtr doc = NULL;
249     xmlXPathContextPtr xpathCtxt = NULL;
250     char * ret = NULL;
251
252     unsigned int xlen = 0;
253     unsigned int alen = 0;
254     char * query = (char *)MALLOC((xlen + alen + 2 + 1) * sizeof(char));
255
256     if (!xpath || !attribute)
257     {
258         return NULL;
259     }
260
261     xlen = (unsigned int) strlen(xpath);
262     alen = (unsigned int) strlen(attribute);
263
264     getDocAndCtxt(&doc, &xpathCtxt);
265     if (doc == NULL)
266     {
267         return NULL;
268     }
269
270     if (query)
271     {
272         sprintf(query, "%s/@%s", xpath, attribute);
273         query[xlen + alen + 2] = '\0';
274
275         ret = strdup(getAttribute(doc, xpathCtxt, (const xmlChar*)query));
276         FREE(query);
277     }
278
279     xmlXPathFreeContext(xpathCtxt);
280     xmlFreeDoc(doc);
281
282     return ret;
283 }
284 /*--------------------------------------------------------------------------*/
285 char ** getPrefAttributesValues(const char * xpath, const char ** attributes, const unsigned int attrLen)
286 {
287     xmlDocPtr doc = NULL;
288     xmlXPathContextPtr xpathCtxt = NULL;
289     xmlXPathObjectPtr xpathObj = NULL;
290     char ** ret = NULL;
291
292     if (!xpath || !attributes || !attrLen)
293     {
294         return NULL;
295     }
296
297     getDocAndCtxt(&doc, &xpathCtxt);
298     if (doc == NULL)
299     {
300         return NULL;
301     }
302
303     ret = (char**)MALLOC(sizeof(char*) * attrLen);
304     xpathObj = xmlXPathEval((const xmlChar*)xpath, xpathCtxt);
305     if (xpathObj && xpathObj->nodesetval && xpathObj->nodesetval->nodeMax)
306     {
307         int i;
308         xmlNode * node = (xmlNode*)xpathObj->nodesetval->nodeTab[0];
309         for (i = 0; i < (int)attrLen; i++)
310         {
311             xmlAttr * attrs = xmlHasProp(node, (const xmlChar *)attributes[i]);
312             if (attrs)
313             {
314                 ret[i] = strdup((const char *)attrs->children->content);
315             }
316             else
317             {
318                 int j;
319                 for (j = 0; j < i; j++)
320                 {
321                     free(ret[j]);
322                 }
323                 FREE(ret);
324                 ret = NULL;
325                 break;
326             }
327         }
328     }
329
330     if (xpathObj)
331     {
332         xmlXPathFreeObject(xpathObj);
333     }
334
335     xmlXPathFreeContext(xpathCtxt);
336     xmlFreeDoc(doc);
337
338     return ret;
339 }
340 /*--------------------------------------------------------------------------*/
341 void setPrefAttributesValues(const char * xpath, const char ** kv, const unsigned int kvLen)
342 {
343     xmlDocPtr doc = NULL;
344     xmlXPathContextPtr xpathCtxt = NULL;
345     xmlXPathObjectPtr xpathObj = NULL;
346     char * SCIHOME = NULL;
347     char * path = NULL;
348     BOOL bConvert = FALSE;
349     char * shortfilename_xml_conf = NULL;
350
351     if (!xpath || !kv || !kvLen)
352     {
353         return;
354     }
355
356     getDocAndCtxt(&doc, &xpathCtxt);
357     if (doc == NULL)
358     {
359         return;
360     }
361
362     xpathObj = xmlXPathEval((const xmlChar*)xpath, xpathCtxt);
363     if (xpathObj && xpathObj->nodesetval && xpathObj->nodesetval->nodeMax)
364     {
365         int i;
366         xmlNode * node = (xmlNode*)xpathObj->nodesetval->nodeTab[0];
367         for (i = 0; i < (int)kvLen / 2; i++)
368         {
369             xmlAttr * attrs = xmlHasProp(node, (const xmlChar *)kv[2 * i]);
370             if (attrs)
371             {
372                 attrs->children->content = xmlStrdup((const xmlChar *)kv[2 * i + 1]);
373             }
374             else
375             {
376                 break;
377             }
378         }
379     }
380
381     if (xpathObj)
382     {
383         xmlXPathFreeObject(xpathObj);
384     }
385
386     xmlXPathFreeContext(xpathCtxt);
387
388     // Save
389     xmlThrDefIndentTreeOutput(1);
390
391     SCIHOME = getSCIHOME();
392     path = (char *)MALLOC(strlen(SCIHOME) + strlen(XCONF));
393
394     sprintf(path, XCONF, SCIHOME);
395     FREE(SCIHOME);
396
397     if (FileExist(path))
398     {
399         shortfilename_xml_conf = getshortpathname(path, &bConvert);
400         if (shortfilename_xml_conf)
401         {
402             xmlSaveFormatFile(shortfilename_xml_conf, doc, 2);
403             FREE(shortfilename_xml_conf);
404             shortfilename_xml_conf = NULL;
405         }
406     }
407
408     FREE(path);
409     path = NULL;
410
411     xmlFreeDoc(doc);
412 }