1
/*============================================================================
3
* This file is part of the Code_Saturne Kernel, element of the
4
* Code_Saturne CFD tool.
6
* Copyright (C) 1998-2009 EDF S.A., France
8
* contact: saturne-support@edf.fr
10
* The Code_Saturne Kernel is free software; you can redistribute it
11
* and/or modify it under the terms of the GNU General Public License
12
* as published by the Free Software Foundation; either version 2 of
13
* the License, or (at your option) any later version.
15
* The Code_Saturne Kernel is distributed in the hope that it will be
16
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
17
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with the Code_Saturne Kernel; if not, write to the
22
* Free Software Foundation, Inc.,
23
* 51 Franklin St, Fifth Floor,
24
* Boston, MA 02110-1301 USA
26
*============================================================================*/
28
/*============================================================================
29
* Management of the GUI parameters file: xpath request and utilities
30
*============================================================================*/
32
#if defined(HAVE_CONFIG_H)
33
#include "cs_config.h"
36
/*----------------------------------------------------------------------------
37
* Standard C library headers
38
*----------------------------------------------------------------------------*/
49
/*----------------------------------------------------------------------------
50
* libxml2 library headers
51
*----------------------------------------------------------------------------*/
53
#if defined(HAVE_LIBXML2)
55
#include <libxml/tree.h>
56
#include <libxml/parser.h>
57
#include <libxml/xpath.h>
58
#include <libxml/xpathInternals.h>
62
/*----------------------------------------------------------------------------
64
*----------------------------------------------------------------------------*/
67
#include <bft_error.h>
68
#include <bft_printf.h>
70
/*----------------------------------------------------------------------------
72
*----------------------------------------------------------------------------*/
76
/*----------------------------------------------------------------------------
77
* Header for the current file
78
*----------------------------------------------------------------------------*/
80
#include "cs_gui_util.h"
83
/*----------------------------------------------------------------------------*/
87
/*=============================================================================
88
* Local Macro Definitions
89
*============================================================================*/
91
#define XML_READER_VERSION 2.0
93
/*=============================================================================
95
*============================================================================*/
97
#if defined(HAVE_LIBXML2)
98
xmlDocPtr docxml = NULL; /* Pointer on the XML document */
99
xmlXPathContextPtr xpathCtx = NULL; /* Pointer on the XPath Context */
100
xmlNodePtr node = NULL; /* Pointer on the root node */
101
const char *xmlRootName = NULL; /* Name of the root node */
104
/*============================================================================
105
* Public Fortran function definitions
106
*============================================================================*/
108
/*-----------------------------------------------------------------------------
109
* Return the information if the requested xml file is missing or not.
113
* SUBROUTINE CSIHMP (IIHMPR)
116
* INTEGER IIHMPR <-- 1 if the file exists, 0 otherwise
117
*----------------------------------------------------------------------------*/
119
void CS_PROCF (csihmp, CSIHMP) (int *const iihmpr)
121
#if defined(HAVE_LIBXML2)
131
/*============================================================================
132
* Public function definitions
133
*============================================================================*/
135
/*----------------------------------------------------------------------------
136
* Load the xml file in memory. Return an error code for the main program.
139
* filename --> xml file containing the parameters
140
*----------------------------------------------------------------------------*/
143
cs_gui_file_loading(const char *const filename)
145
#if defined(HAVE_LIBXML2)
147
int file_descriptor = 0;
152
/* Verification of the existence of the file while opening it */
154
file_descriptor = open(filename, O_RDONLY);
156
if (file_descriptor == -1) {
158
cs_base_warn(__FILE__, __LINE__);
159
bft_printf( _("Unable to open the file: %s\n"), filename);
166
/* If file exists, close it. It will be reopen by xmlParseFile */
167
close(file_descriptor);
171
/* libxml initialization */
175
/* Loading the xml file */
176
docxml = xmlParseFile(filename);
179
if (docxml == NULL) {
181
cs_base_warn(__FILE__, __LINE__);
182
bft_printf (_("Unable to parse the file: %s\n"), filename);
188
/* Contexte definition */
189
xpathCtx = xmlXPathNewContext(docxml);
191
/* Get the root node of the xml document and more particularly
193
node = xmlDocGetRootElement(docxml);
194
xmlRootName = (const char*) node->name;
198
/* Check the Interface version */
199
cs_gui_get_version();
205
bft_error(__FILE__, __LINE__, 0,
206
_("Code_Saturne has been compiled without Xml support."));
213
/*-----------------------------------------------------------------------------
214
* Check the xml file version.
215
*----------------------------------------------------------------------------*/
218
cs_gui_get_version(void)
222
double version_number;
223
double version_sat = XML_READER_VERSION;
225
double maj_sat, min_sat;
227
path = cs_xpath_init_path();
228
cs_xpath_add_attribute(&path, "version");
230
version = cs_gui_get_attribute_value(path);
231
version_number = atof(version);
233
minus = modf(version_number, &major);
234
min_sat = modf(version_sat, &maj_sat);
236
if (major != maj_sat)
237
bft_error(__FILE__, __LINE__, 0,
238
_("========================================================\n"
239
" ** INVALID VERSION OF THE XML FILE\n"
240
" -------------------------------------- \n"
241
" XML FILE VERSION: %.1f \n"
242
" XML READER VERSION: %.1f \n"
243
"========================================================\n"),
244
version_number, version_sat);
246
if (minus != min_sat) {
248
cs_base_warn(__FILE__, __LINE__);
249
bft_printf(_("========================================================\n"
250
" ** INCOMPATIBLE VERSION OF THE XML FILE\n"
251
" -------------------------------------- \n"
252
" XML FILE VERSION: %.1f \n"
253
" XML READER VERSION: %.1f \n"
255
" YOU SHOULD RESTART YOUR CALCUL WITH A NEW XML FILE\n"
256
"========================================================\n"),
257
version_number, version_sat);
265
/*----------------------------------------------------------------------------
266
* Initialize the path for the xpath request with the root node.
267
* Return the root path.
268
*----------------------------------------------------------------------------*/
271
cs_xpath_init_path(void)
273
#if defined(HAVE_LIBXML2)
277
BFT_MALLOC(path, strlen("/") + strlen(xmlRootName) + 1, char);
279
strcat(path, xmlRootName);
285
bft_error(__FILE__, __LINE__, 0,
286
_("Code_Saturne has been compiled without Xml support."));
293
/*----------------------------------------------------------------------------
294
* Initialize the path for the xpath request with a short way.
295
* Return the short path.
296
*----------------------------------------------------------------------------*/
299
cs_xpath_short_path(void)
303
BFT_MALLOC(path, strlen("/")+1, char);
309
/*----------------------------------------------------------------------------
310
* Add all element (*) to the path.
313
* path <--> path for the xpath request
314
*----------------------------------------------------------------------------*/
317
cs_xpath_add_all_elements(char **path)
322
strlen(*path) +strlen("/*") +1,
328
/*----------------------------------------------------------------------------
329
* Add an element (i.e. markup's label) to the path.
332
* path <--> path for the xpath request
333
* element --> label of the new element in the path
334
*----------------------------------------------------------------------------*/
337
cs_xpath_add_element( char ** path,
338
const char *const element)
342
if (element != NULL) {
345
strlen(*path)+ strlen(element)+ strlen("/") +1,
349
strcat(*path, element);
354
/*----------------------------------------------------------------------------
355
* Add a list of elements (i.e. markup's label) to the path.
358
* path <--> path for the xpath request
359
* nbr --> size of the labels list
360
* ... --> list of labels of new elements in the path
361
*----------------------------------------------------------------------------*/
364
cs_xpath_add_elements( char **path,
375
for(i=0; i<nbr; i++) {
377
elt = va_arg(list, char *);
382
strlen(*path)+ strlen(elt)+ strlen("/") +1,
393
/*----------------------------------------------------------------------------
394
* Add an element's attribute to the path.
397
* path <--> path for the xpath request
398
* attribute_name --> label of the new attribute in the path
399
*----------------------------------------------------------------------------*/
402
cs_xpath_add_attribute( char **path,
403
const char *const attribute_name)
406
assert(attribute_name);
409
strlen(*path)+ strlen(attribute_name)+ strlen("/@")+1,
413
strcat(*path, attribute_name);
416
/*----------------------------------------------------------------------------
417
* Add the i'st element to the path.
420
* path <--> path for the xpath request
421
* element --> label of the new element in the path
422
* num --> number of the element's markup
423
*----------------------------------------------------------------------------*/
426
cs_xpath_add_element_num( char ** path,
427
const char *const element,
436
nfigures = cs_gui_characters_number(num);
438
BFT_MALLOC(strnum, nfigures+1, char);
450
strcat(*path, element);
451
sprintf(strnum,"%d", num);
453
strcat(*path, strnum);
459
/*----------------------------------------------------------------------------
460
* Add a test on a value associated to an attribute to the path.
463
* path <--> path for the xpath request
464
* attribute_type --> label of the attribute for the test in the path
465
* attribute_value --> value of the attribute for the test in the path
466
*----------------------------------------------------------------------------*/
469
cs_xpath_add_test_attribute( char ** path,
470
const char *const attribute_type,
471
const char *const attribute_value)
474
assert(attribute_type);
475
assert(attribute_value);
477
BFT_REALLOC(*path, strlen(*path)+
479
strlen(attribute_type)+
481
strlen(attribute_value)+
486
strcat(*path, attribute_type);
488
strcat(*path, attribute_value);
492
/*----------------------------------------------------------------------------
493
* Add the 'text()' xpath function to the path.
496
* path <--> path for the xpath request
497
*----------------------------------------------------------------------------*/
500
cs_xpath_add_function_text(char **path)
505
strlen(*path)+ strlen("/text()")+1,
508
strcat(*path, "/text()");
511
/*----------------------------------------------------------------------------
512
* Return a list of attributes nodes name from the xpath request in an array.
513
* Example: from <a attr="c"/><b attr="d"/> return {c,d}
516
* path --> path for the xpath request
517
* size <-- array size
518
*----------------------------------------------------------------------------*/
521
cs_gui_get_attribute_values(char *const path,
524
#if defined(HAVE_LIBXML2)
526
char **nodes_name = NULL;
529
xmlXPathObjectPtr xpathObj;
534
xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx);
536
if (xpathObj == NULL)
537
bft_error(__FILE__, __LINE__, 0, _("Invalid xpath: %s\n"), path);
539
nodes = xpathObj->nodesetval;
540
*size = (nodes) ? nodes->nodeNr : 0;
544
BFT_MALLOC(nodes_name, *size, char*);
546
for (i =0; i < *size; i++) {
547
assert(nodes->nodeTab[0]);
549
if (nodes->nodeTab[i]->type == XML_ATTRIBUTE_NODE) {
550
cur = nodes->nodeTab[i];
551
BFT_MALLOC(nodes_name[i],
552
strlen((char *) cur->children->content)+1,
554
strcpy(nodes_name[i], (char*) cur->children->content);
557
bft_error(__FILE__, __LINE__, 0,
558
_("The node type is not XML_ATTRIBUTE_NODE.\nXpath: %s\n"),
563
xmlXPathFreeObject(xpathObj);
568
bft_error(__FILE__, __LINE__, 0,
569
_("Code_Saturne has been compiled without Xml support."));
576
/*----------------------------------------------------------------------------
577
* Return the value of an element's attribute.
578
* Example: from <a b="c"/> return c
581
* path --> path for the xpath request
582
*----------------------------------------------------------------------------*/
585
cs_gui_get_attribute_value(char *const path)
591
array = cs_gui_get_attribute_values(path, &size);
593
if ((array == NULL) || (size == 0))
597
bft_error(__FILE__, __LINE__, 0,
598
_("Several attributes found: %i \n"
599
"The first one is %s \nXpath: %s\n"),
600
size, array[0], path);
602
BFT_MALLOC(attr, strlen(array[0])+1, char);
603
strcpy(attr, array[0]);
611
/*----------------------------------------------------------------------------
612
* Return a list of children nodes name from the xpath request in an array.
613
* Example: from <a>3<\a><b>4<\b> return {a,b}
616
* path --> path for the xpath request
617
* size <-- array size
618
*----------------------------------------------------------------------------*/
621
cs_gui_get_nodes_name(char *const path,
624
#if defined(HAVE_LIBXML2)
626
char **nodes_name = NULL;
627
xmlXPathObjectPtr xpathObj;
634
xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx);
636
if (xpathObj == NULL)
637
bft_error(__FILE__, __LINE__, 0, _("Invalid xpath: %s\n"), path);
639
nodes = xpathObj->nodesetval;
640
*size = (nodes) ? nodes->nodeNr : 0;
644
BFT_MALLOC(nodes_name, *size, char*);
646
for (i =0; i < *size; i++) {
647
assert(nodes->nodeTab[0]);
649
if (nodes->nodeTab[i]->type == XML_ELEMENT_NODE) {
650
cur = nodes->nodeTab[i];
651
BFT_MALLOC(nodes_name[i], strlen((const char *) cur->name)+1, char);
652
strcpy(nodes_name[i], (const char*) cur->name);
654
bft_error(__FILE__, __LINE__, 0,
655
_("The node type is not XML_ELEMENT_NODE.\nXpath: %s\n"),
660
xmlXPathFreeObject(xpathObj);
665
bft_error(__FILE__, __LINE__, 0,
666
_("Code_Saturne has been compiled without Xml support."));
674
/*----------------------------------------------------------------------------
675
* Return a single node's name from the xpath request.
678
* path --> path for the xpath request
679
*----------------------------------------------------------------------------*/
682
cs_gui_get_node_name(char *const path)
688
array = cs_gui_get_nodes_name(path, &size);
690
if ((array == NULL) || (size == 0))
694
bft_error(__FILE__, __LINE__, 0,
695
_("Several nodes name found: %i \n"
696
"The first one is %s \nXpath: %s\n"),
697
size, array[0], path);
699
BFT_MALLOC(name, strlen(array[0])+1, char);
700
strcpy(name, array[0]);
708
/*----------------------------------------------------------------------------
709
* Return a list of children text nodes from the xpath request in an array.
710
* Example: from <a>3<\a><a>4<\a> return {3,4}
713
* path --> path for the xpath request
714
* size <-- array size
715
*----------------------------------------------------------------------------*/
718
cs_gui_get_text_values(char *const path,
721
#if defined(HAVE_LIBXML2)
723
char **text_name = NULL;
724
xmlXPathObjectPtr xpathObj;
731
xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx);
733
if (xpathObj == NULL)
734
bft_error(__FILE__, __LINE__, 0, _("Invalid xpath: %s\n"), path);
736
nodes = xpathObj->nodesetval;
737
*size = (nodes) ? nodes->nodeNr : 0;
741
BFT_MALLOC(text_name, *size, char*);
743
for (i =0; i < *size; i++) {
745
assert(nodes->nodeTab[0]);
747
if (nodes->nodeTab[i]->type == XML_TEXT_NODE) {
748
cur = nodes->nodeTab[i];
749
BFT_MALLOC(text_name[i], strlen((char *) cur->content)+1, char);
750
strcpy(text_name[i], (char*) cur->content);
753
bft_error(__FILE__, __LINE__, 0,
754
_("The node type is not XML_TEXT_NODE.\nXpath: %s\n"),
759
xmlXPathFreeObject(xpathObj);
764
bft_error(__FILE__, __LINE__, 0,
765
_("Code_Saturne has been compiled without Xml support."));
772
/*----------------------------------------------------------------------------
773
* Return a single children text node from the xpath request.
776
* path --> path for the xpath request
777
*----------------------------------------------------------------------------*/
780
cs_gui_get_text_value(char *const path)
786
array = cs_gui_get_text_values(path, &size);
788
if ((array == NULL) || (size == 0))
792
bft_error(__FILE__, __LINE__, 0,
793
_("Several text node found: %i \n"
794
"The first one is %s \nXpath: %s\n"),
795
size, array[0], path);
797
BFT_MALLOC(text, strlen(array[0])+1, char);
798
strcpy(text, array[0]);
806
/*----------------------------------------------------------------------------
807
* Modify the value parameter and return 1 if the xpath request succeeded,
808
* otherwise just return 0.
811
* path --> path for the xpath request
812
* value <-- double result of the xpath request
813
*----------------------------------------------------------------------------*/
816
cs_gui_get_double(char *const path,
819
char *text_name = NULL;
822
text_name = cs_gui_get_text_value(path);
824
if (text_name == NULL)
827
*value = atof(text_name);
834
/*----------------------------------------------------------------------------
835
* Modify the value parameter and return 1 if the xpath request succeeded,
836
* otherwise just return 0.
839
* path --> path for the xpath request
840
* value <-- integer result of the xpath request
841
*----------------------------------------------------------------------------*/
844
cs_gui_get_int(char *const path,
847
char *text_name = NULL;
850
text_name = cs_gui_get_text_value(path);
852
if (text_name == NULL)
855
*value = atoi(text_name);
862
/*----------------------------------------------------------------------------
863
* Return the number of elements (i.e. the number of xml markups)
864
* from a xpath request.
865
* Example: from <a>3<\a><a>4<\a> return 2
868
* path --> path for the xpath request
869
*----------------------------------------------------------------------------*/
872
cs_gui_get_nb_element(char *const path)
874
#if defined(HAVE_LIBXML2)
876
xmlXPathObjectPtr xpathObj;
881
xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx);
883
if (xpathObj == NULL)
884
bft_error(__FILE__, __LINE__, 0, _("Invalid xpath: %s\n"), path);
886
nb = (xpathObj->nodesetval) ? xpathObj->nodesetval->nodeNr : 0;
888
xmlXPathFreeObject(xpathObj);
894
bft_error(__FILE__, __LINE__, 0,
895
_("Code_Saturne has been compiled without Xml support."));
902
/*----------------------------------------------------------------------------
903
* Return the integer max value from a list, which is a xpath request result.
904
* Example: from <a>3<\a><a>4<\a> return 4
907
* path --> path for the xpath request
908
*----------------------------------------------------------------------------*/
911
cs_gui_get_max_value(char *const path)
913
#if defined(HAVE_LIBXML2)
915
xmlXPathObjectPtr xpathObj;
924
xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx);
926
if (xpathObj == NULL)
927
bft_error(__FILE__, __LINE__, 0, _("Invalid xpath: %s\n"), path);
929
nodes=xpathObj->nodesetval;
930
size = (nodes) ? nodes->nodeNr : 0;
933
bft_error (__FILE__, __LINE__, 0, _("No markup found: %s \n"), path);
936
for (i=0; i <size; i++) {
937
assert(nodes->nodeTab[i]);
938
if(nodes->nodeTab[i]->type == XML_TEXT_NODE) {
939
cur = nodes->nodeTab[i];
940
max_val = CS_MAX(max_val, atoi((char*) cur->content));
943
bft_error(__FILE__, __LINE__, 0,
944
_("The node type is not XML_TEXT_NODE.\nXpath: %s\n"), path);
949
xmlXPathFreeObject(xpathObj);
955
bft_error(__FILE__, __LINE__, 0,
956
_("Code_Saturne has been compiled without Xml support."));
963
/*-----------------------------------------------------------------------------
964
* Evaluate the "status" attribute value.
965
* Return 1 if the xpath request has succeeded, 0 otherwise.
968
* path --> path for the xpath request
969
* result <-- status="on" return 1, status="off" return 0
970
*----------------------------------------------------------------------------*/
973
cs_gui_get_status(char *const path,
979
status = cs_gui_get_attribute_value(path);
986
if (cs_gui_strcmp(status, "on"))
988
else if (cs_gui_strcmp(status, "off"))
991
bft_error(__FILE__, __LINE__, 0,
992
_("Invalid attribute value: %s \nXpath: %s\n"), status, path);
1000
/*-----------------------------------------------------------------------------
1001
* Return the xml markup quantity
1004
* markup --> path for the markup
1005
* flag --> 1: initialize the path with the root node;
1006
* 0: initialize the path with a short way
1007
*----------------------------------------------------------------------------*/
1010
cs_gui_get_tag_number(const char *const markup, const int flag)
1016
path = cs_xpath_init_path();
1018
BFT_MALLOC(path, strlen("/")+1, char);
1021
cs_xpath_add_element(&path, markup);
1022
number = cs_gui_get_nb_element(path);
1029
/*-----------------------------------------------------------------------------
1030
* Return the number of characters needed to write an integer number
1033
* num --> integer number
1034
*----------------------------------------------------------------------------*/
1037
cs_gui_characters_number(const int num)
1047
for (i=1; i <= num; i *= 10)
1053
/*-----------------------------------------------------------------------------
1054
* Comparison between two string: return 1 if the two string are equal, 0
1058
* s1 --> first string
1059
* s2 --> second string
1060
*----------------------------------------------------------------------------*/
1063
cs_gui_strcmp(const char *const s1,
1064
const char *const s2)
1066
if (s1 == NULL || s2 == NULL) return 0;
1067
if ( strlen(s1) != strlen(s2)) return 0;
1068
if (!strncmp(s1, s2, strlen(s1))) return 1;
1072
/*-----------------------------------------------------------------------------
1073
* Copy a C string into a Fortran string.
1076
* chainef <--> Fortran string
1077
* chainc --> C string
1078
* lstrF --> maximum length of the Fortran string
1079
*----------------------------------------------------------------------------*/
1082
cs_gui_strcpy_c2f( char *const chainef,
1083
const char *const chainec,
1088
assert(chainec != NULL);
1091
strncpy(chainef, chainec, strlen(chainec));
1093
for (i = strlen(chainec); i < lstrF ; i++)
1097
/*----------------------------------------------------------------------------*/