* Fix a bug on the xpath query. It was talking all nodes, even the one from
[scilab.git] / scilab / modules / jvm / src / c / getJvmOptions.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2008 - 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
13 /*--------------------------------------------------------------------------*/
14 #include <stdlib.h>
15 #include <libxml/xpath.h>
16 #include <libxml/xmlreader.h>
17 #include "getJvmOptions.h"
18 #include "GetXmlFileEncoding.h"
19 #include "MALLOC.h"
20 #include "localization.h"
21 #include "machine.h"
22 #include "stricmp.h"
23 #include "FileExist.h"
24 #ifdef _MSC_VER
25 #include "strdup_windows.h"
26 #endif
27 #include "strsubst.h"
28 #include "getos.h"
29 #include "getshortpathname.h"
30 #include "BOOL.h"
31 #include "getScilabPreference.h"
32
33 static char * getJavaHeapSize(void);
34 /*--------------------------------------------------------------------------*/
35 JavaVMOption * getJvmOptions(char *SCI_PATH, char *filename_xml_conf, int *size_JavaVMOption)
36 {
37     if ( FileExist(filename_xml_conf) )
38     {
39         JavaVMOption *jvm_options = NULL;
40         char *encoding = GetXmlFileEncoding(filename_xml_conf);
41
42         /* Don't care about line return / empty line */
43         xmlKeepBlanksDefault(0);
44         /* check if the XML file has been encoded with utf8 (unicode) or not */
45         if (stricmp("utf-8", encoding) == 0)
46         {
47             xmlDocPtr doc = NULL;
48             xmlXPathContextPtr xpathCtxt = NULL;
49             xmlXPathObjectPtr xpathObj = NULL;
50             char *jvm_option_string = NULL;
51             char *xpath_query = NULL;
52             char *heapSize = getJavaHeapSize();
53
54             int indice = 0;
55             {
56                 BOOL bConvert = FALSE;
57                 char *shortfilename_xml_conf = getshortpathname(filename_xml_conf, &bConvert);
58                 if (shortfilename_xml_conf)
59                 {
60                     doc = xmlParseFile (shortfilename_xml_conf);
61                     FREE(shortfilename_xml_conf);
62                     shortfilename_xml_conf = NULL;
63                 }
64             }
65
66             if (doc == NULL)
67             {
68                 fprintf(stderr, _("Error: Could not parse file %s.\n"), filename_xml_conf);
69                 if (encoding)
70                 {
71                     FREE(encoding);
72                     encoding = NULL;
73                 }
74                 FREE(heapSize);
75                 *size_JavaVMOption = 0;
76                 return NULL;
77             }
78
79             xpathCtxt = xmlXPathNewContext(doc);
80             /* Retrieve all nodes without the os tag + only the one from our operating system */
81 #define XPATH_QUERY "//jvm_options/option[not(@os)] | //jvm_options/option[@os='%s']"
82
83             xpath_query = (char *)MALLOC(sizeof(char) * ((int)strlen(XPATH_QUERY) + (int)strlen(OSNAME) + 1));
84             sprintf(xpath_query, XPATH_QUERY, OSNAME);
85
86             xpathObj = xmlXPathEval((const xmlChar*)xpath_query, xpathCtxt);
87             FREE(xpath_query);
88             if (xpathObj && xpathObj->nodesetval->nodeMax)
89             {
90                 /* the Xpath has been understood and there are node */
91                 int i;
92                 char heapSizeUsed = 0;
93                 for (i = 0; i < xpathObj->nodesetval->nodeNr; i++)
94                 {
95
96                     xmlAttrPtr attrib = xpathObj->nodesetval->nodeTab[i]->properties;
97                     /* Get the properties of <option>  */
98                     while (attrib != NULL)
99                     {
100                         /* loop until when have read all the attributes */
101                         if (xmlStrEqual (attrib->name, (const xmlChar*) "value"))
102                         {
103                             /* we found the tag name */
104                             const char *str = (const char*)attrib->children->content;
105                             if (strstr(str, "-Xmx") == str && heapSize)
106                             {
107                                 jvm_option_string = heapSize;
108                                 heapSizeUsed = 1;
109                             }
110                             else
111                             {
112                                 jvm_option_string = strdup(str);
113                             }
114                         }
115                         attrib = attrib->next;
116                     }
117
118                     if ( (jvm_option_string) && (strlen(jvm_option_string) > 0) )
119                     {
120                         char *option_string_path_separator = NULL;
121                         char *option_string_sci_path = NULL;
122
123                         option_string_path_separator = strsub(jvm_option_string, "$PATH_SEPARATOR", PATH_SEPARATOR);
124
125                         if (jvm_option_string)
126                         {
127                             FREE(jvm_option_string);
128                         }
129
130                         option_string_sci_path = strsub(option_string_path_separator, "$SCILAB", SCI_PATH);
131                         if (option_string_sci_path)
132                         {
133                             FREE(option_string_path_separator);
134                         }
135
136                         jvm_options = (JavaVMOption *)REALLOC(jvm_options, sizeof(JavaVMOption) * (indice + 1));
137                         jvm_options[indice].optionString = option_string_sci_path;
138                         indice++;
139                     }
140
141                 }
142
143                 if (!heapSizeUsed)
144                 {
145                     FREE(heapSize);
146                 }
147             }
148
149             if (xpathObj) xmlXPathFreeObject(xpathObj);
150             if (xpathCtxt) xmlXPathFreeContext(xpathCtxt);
151             xmlFreeDoc (doc);
152
153             /* xmlCleanupParser is called in
154              * modules/core/src/c/TerminateCore.c
155              * since it needs to be done only once.
156              */
157
158             if (getenv("SCI_JAVA_ENABLE_HEADLESS") != NULL)
159             {
160                 /* When Scilab is built from a virtual machine, it needs
161                  * an X11 server / input
162                  * This is only called by "make doc" by the SCI/Makefile.am
163                  */
164 #define HEADLESS "-Djava.awt.headless=true"
165                 jvm_options = (JavaVMOption *)REALLOC(jvm_options, sizeof(JavaVMOption) * (indice + 1));
166                 jvm_options[indice].optionString = MALLOC((strlen(HEADLESS) + 1) * sizeof(char));
167                 strcpy(jvm_options[indice].optionString, HEADLESS);
168                 indice++;
169 #undef HEADLESS
170             }
171
172             if (encoding)
173             {
174                 FREE(encoding);
175                 encoding = NULL;
176             }
177
178             *size_JavaVMOption = indice;
179             return jvm_options;
180         }
181         else
182         {
183             fprintf(stderr, _("Error: Not a valid configuration file %s (encoding not '%s') Encoding '%s' found.\n"), filename_xml_conf, "utf-8", encoding);
184         }
185         if (encoding)
186         {
187             FREE(encoding);
188             encoding = NULL;
189         }
190     }
191     return NULL;
192 }
193 /*--------------------------------------------------------------------------*/
194 char * getJavaHeapSize(void)
195 {
196     const char * value = getScilabPreferences()->heapSize;
197     char * rvalue = NULL;
198     int ivalue;
199
200     if (value)
201     {
202         ivalue = (int)atof(value);
203         if (ivalue > 0)
204         {
205             rvalue = (char *)MALLOC(24 * sizeof(char));
206             sprintf(rvalue, "-Xmx%dm", ivalue);
207         }
208     }
209
210     return rvalue;
211 }