/*============================================================================ * * Code_Saturne version 1.3 * ------------------------ * * * This file is part of the Code_Saturne Kernel, element of the * Code_Saturne CFD tool. * * Copyright (C) 1998-2007 EDF S.A., France * * contact: saturne-support@edf.fr * * The Code_Saturne Kernel is free software; you can redistribute it * and/or modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * The Code_Saturne Kernel is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with the Code_Saturne Kernel; if not, write to the * Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA * *============================================================================*/ /*============================================================================ * Reader of the parameters file: xpath request and utilities *============================================================================*/ #if defined(_CS_HAVE_XML) /*---------------------------------------------------------------------------- * Standard C library headers *----------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include /*---------------------------------------------------------------------------- * BFT library headers *----------------------------------------------------------------------------*/ #include #include #include /*---------------------------------------------------------------------------- * libxml2 library headers *----------------------------------------------------------------------------*/ #include #include #include #include /*---------------------------------------------------------------------------- * Local headers *----------------------------------------------------------------------------*/ #include "cs_base.h" #include "cs_msg.h" /*---------------------------------------------------------------------------- * Header for the current file *----------------------------------------------------------------------------*/ #include "cs_gui_util.h" /*----------------------------------------------------------------------------*/ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /*============================================================================= * Local Macro Definitions *============================================================================*/ #define XML_READER_VERSION 0.0 /*---------------------------------------------------------------------------- * Global variables *----------------------------------------------------------------------------*/ xmlDocPtr docxml = NULL; /* Pointer on the XML document */ xmlXPathContextPtr xpathCtx = NULL; /* Pointer on the XPath Context */ xmlNodePtr node = NULL; /* Pointer on the root node */ const char *xmlRootName = NULL; /* Name of the root node */ /*----------------------------------------------------------------------------- * Return the information if the requested xml file is missing or not. * * Fortran Interface: * * SUBROUTINE CSIHMP (ITURB, IDEUCH, IGRAKE, IGRAKI) * ***************** * * INTEGER IIHMPR <-- 1 if the file exists, 0 otherwise *----------------------------------------------------------------------------*/ void CS_PROCF (csihmp, CSIHMP) (int *const iihmpr) { if (docxml == NULL) *iihmpr = 0; else *iihmpr = 1; } /*---------------------------------------------------------------------------- * Load the xml file in memory. Return an error code for the main programme. * * parameter: * filename --> xml file containing the parameters *----------------------------------------------------------------------------*/ int cs_gui_file_loading(const char *const filename) { int file_descriptor = 0; int argerr = 0; assert(filename); /* Vérification de l'existence du fichier par son ouverture */ file_descriptor = open(filename, O_RDONLY); if (file_descriptor == -1) { cs_base_warn(__FILE__, __LINE__); bft_printf( _("Unable to open the file: %s\n"), filename); argerr = 2; return argerr; } else { /* Si le fichier existe, on le referme. Il sera réouvert par xmlParseFile */ close(file_descriptor); } /* libxml initialization */ xmlInitParser(); LIBXML_TEST_VERSION /* Loading the xml file */ docxml = xmlParseFile(filename); if (docxml == NULL) { cs_base_warn(__FILE__, __LINE__); bft_printf (_("Unable to parse the file: %s\n"), filename); argerr = 2; } else { /* Contexte definition */ xpathCtx = xmlXPathNewContext(docxml); /* Récupération du noeud racine du document xml et plus particulièrement de son label */ node = xmlDocGetRootElement(docxml); xmlRootName = (const char*) node->name; } /* Verification de la version de l'interface */ cs_gui_get_version(); return argerr; } /*----------------------------------------------------------------------------- * Check the xml file version. *----------------------------------------------------------------------------*/ void cs_gui_get_version(void) { char *path; char *version; double version_number; double version_sat = XML_READER_VERSION; double major; double maj_sat; double min_sat; double minus; path = cs_xpath_init_path(); cs_xpath_add_attribute(&path, "version"); version = cs_gui_get_attribute_value(path); version_number = atof(version); minus = modf(version_number, &major); min_sat = modf(version_sat, &maj_sat); if(major != maj_sat) bft_error(__FILE__, __LINE__, 0, _("========================================================\n" " ** INVALID VERSION OF THE XML FILE\n" " -------------------------------------- \n" " XML FILE VERSION: %.1f \n" " XML READER VERSION: %.1f \n" "========================================================\n"), version_number, version_sat); if(minus != min_sat) { cs_base_warn(__FILE__, __LINE__); bft_printf(_("========================================================\n" " ** INCOMPATIBLE VERSION OF THE XML FILE\n" " -------------------------------------- \n" " XML FILE VERSION: %.1f \n" " XML READER VERSION: %.1f \n" "\n" " YOU SHOULD RESTART YOUR CALCUL WITH A NEW XML FILE\n" "========================================================\n"), version_number, version_sat); } BFT_FREE(version); BFT_FREE(path); } /*---------------------------------------------------------------------------- * Initialize the path for the xpath request with the root node. * Return the root path. *----------------------------------------------------------------------------*/ char* cs_xpath_init_path(void) { char *path = NULL; BFT_MALLOC(path, strlen(cs_xpath_char_name[SEPARATOR])+ strlen(xmlRootName)+1, char); strcpy(path, cs_xpath_char_name[SEPARATOR]); strcat(path, xmlRootName); return path; } /*---------------------------------------------------------------------------- * Initialize the path for the xpath request with a short way. * Return the short path. *----------------------------------------------------------------------------*/ char* cs_xpath_short_path(void) { char *path = NULL; BFT_MALLOC(path, /* strlen(cs_xpath_char_name[SEPARATOR])+ */ strlen(cs_xpath_char_name[SEPARATOR])+1, char); strcpy(path, cs_xpath_char_name[SEPARATOR]); /* strcat(path, cs_xpath_char_name[SEPARATOR]); */ return path; } /*---------------------------------------------------------------------------- * Add all element (*) to the path. * * parameter: * path <--> path for the xpath request *----------------------------------------------------------------------------*/ void cs_xpath_add_all_elements(char **path) { assert(path); BFT_REALLOC(*path, strlen(*path)+ strlen(cs_xpath_char_name[ALL])+ strlen(cs_xpath_char_name[SEPARATOR]) +1, char); strcat(*path, cs_xpath_char_name[SEPARATOR]); strcat(*path, cs_xpath_char_name[ALL]); } /*---------------------------------------------------------------------------- * Add an element (i.e. markup's label) to the path. * * parameters: * path <--> path for the xpath request * element --> label of the new element in the path *----------------------------------------------------------------------------*/ void cs_xpath_add_element( char ** path, const char *const element) { assert(path); BFT_REALLOC(*path, strlen(*path)+ strlen(element)+ strlen(cs_xpath_char_name[SEPARATOR]) +1, char); strcat(*path, cs_xpath_char_name[SEPARATOR]); strcat(*path, element); } /*---------------------------------------------------------------------------- * Add a list of elements (i.e. markup's label) to the path. * * parameters: * path <--> path for the xpath request * nbr --> size of the labels list * ... --> list of labels of new elements in the path *----------------------------------------------------------------------------*/ void cs_xpath_add_elements( char **path, const int nbr, ...) { va_list list; char *elt = NULL; int i; assert(path); va_start(list, nbr); for(i=0; i path for the xpath request * attribute_name --> label of the new attribute in the path *----------------------------------------------------------------------------*/ void cs_xpath_add_attribute( char **path, const char *const attribute_name) { assert(path); assert(attribute_name); BFT_REALLOC(*path, strlen(*path)+ strlen(attribute_name)+ strlen(cs_xpath_char_name[SEPARATOR])+ strlen(cs_xpath_char_name[ATTRIBUTE])+1, char); strcat(*path, cs_xpath_char_name[SEPARATOR]); strcat(*path, cs_xpath_char_name[ATTRIBUTE]); strcat(*path, attribute_name); return; } /*---------------------------------------------------------------------------- * Add the i'st element to the path. * * parameters: * path <--> path for the xpath request * element --> label of the new element in the path * num --> number of the element's markup *----------------------------------------------------------------------------*/ void cs_xpath_add_element_num( char ** path, const char *const element, const int num) { int nfigures = 0; char *strnum = NULL; assert(path); assert(element); nfigures = cs_gui_characters_number(num); BFT_MALLOC(strnum, nfigures+1, char); BFT_REALLOC(*path, strlen(*path)+ strlen(element)+ strlen(cs_xpath_char_name[SEPARATOR])+ strlen(cs_xpath_char_name[LEFT])+ nfigures+ strlen(cs_xpath_char_name[RIGHT])+1, char); strcat(*path, cs_xpath_char_name[SEPARATOR]); strcat(*path, element); sprintf(strnum,"%d", num); strcat(*path, cs_xpath_char_name[LEFT]); strcat(*path, strnum); strcat(*path, cs_xpath_char_name[RIGHT]); BFT_FREE(strnum); } /*---------------------------------------------------------------------------- * Add a test on a value associated to an attribute to the path. * * parameters: * path <--> path for the xpath request * attribute_type --> label of the attribute for the test in the path * attribute_value --> value of the attribute for the test in the path *----------------------------------------------------------------------------*/ void cs_xpath_add_test_attribute( char ** path, const char *const attribute_type, const char *const attribute_value) { assert(path); assert(attribute_type); assert(attribute_value); BFT_REALLOC(*path, strlen(*path)+ strlen(cs_xpath_char_name[LEFT])+ strlen(cs_xpath_char_name[ATTRIBUTE])+ strlen(attribute_type)+ strlen(cs_xpath_char_name[EQUAL])+ strlen(cs_xpath_char_name[QUOTE])+ strlen(attribute_value)+ strlen(cs_xpath_char_name[QUOTE])+ strlen(cs_xpath_char_name[RIGHT])+1, char); strcat(*path, cs_xpath_char_name[LEFT]); strcat(*path, cs_xpath_char_name[ATTRIBUTE]); strcat(*path, attribute_type); strcat(*path, cs_xpath_char_name[EQUAL]); strcat(*path, cs_xpath_char_name[QUOTE]); strcat(*path, attribute_value); strcat(*path, cs_xpath_char_name[QUOTE]); strcat(*path, cs_xpath_char_name[RIGHT]); } /*---------------------------------------------------------------------------- * Add the 'text()' xpath function to the path. * * parameter: * path <--> path for the xpath request *----------------------------------------------------------------------------*/ void cs_xpath_add_function_text(char **path) { assert(path); BFT_REALLOC(*path, strlen(*path)+ strlen(cs_xpath_char_name[SEPARATOR])+ strlen(cs_xpath_char_name[FTEXT])+1, char); strcat(*path, cs_xpath_char_name[SEPARATOR]); strcat(*path, cs_xpath_char_name[FTEXT]); return; } /*---------------------------------------------------------------------------- * Return the value of an element's attribute. * Example: from return c * * parameter: * path --> path for the xpath request *----------------------------------------------------------------------------*/ char* cs_gui_get_attribute_value(char *const path) { char *model_name = NULL; xmlNodeSetPtr nodes; xmlNodePtr cur; xmlXPathObjectPtr xpathObj; int size; assert(path); /* Evaluation de la requete */ xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx); /* Diverses verifications*/ if (xpathObj == NULL) bft_error(__FILE__, __LINE__, 0, _("Invalid xpath: %s\n"), path); /* On cherche la valeur de l'attribut */ nodes = xpathObj->nodesetval; size = (nodes) ? nodes->nodeNr : 0; /* Si aucun element on retourne le pointeur nul */ if (size == 0) return NULL; if (size > 1) bft_error(__FILE__, __LINE__, 0, _("Several attributes found with xpath: %s\n"), path); assert(nodes->nodeTab[0]); if (nodes->nodeTab[0]->type != XML_ATTRIBUTE_NODE) { bft_error(__FILE__, __LINE__, 0, _("The node type is not XML_ATTRIBUTE_NODE.\nXpath: %s\n"), path); } /* On cherche la valeur de l'attribut */ cur = nodes->nodeTab[0]; BFT_MALLOC(model_name, strlen((char*) cur->children->content)+1, char); strcpy(model_name, (char *)cur->children->content); /* nettoyage */ xmlXPathFreeObject(xpathObj); return model_name; } /*---------------------------------------------------------------------------- * Get a list of children nodes name from the xpath request in an array. * Example: from 3<\a>4<\b> nodes_name = {a,b} * * parameters: * path --> path for the xpath request * nodes_name <-- array of nodes name * size <-- array size *----------------------------------------------------------------------------*/ void cs_gui_get_nodes_name(char *const path, char *** nodes_name, int *const size) { xmlXPathObjectPtr xpathObj; xmlNodeSetPtr nodes; xmlNodePtr cur; int i; assert(path); /* Evaluation de la requete */ xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx); if (xpathObj == NULL) { *size = 0; *nodes_name = NULL; return; } nodes = xpathObj->nodesetval; *size = (nodes) ? nodes->nodeNr : 0; if (*size == 0) *nodes_name = NULL; else { BFT_MALLOC(*nodes_name, *size, char*); for (i =0; i < *size; i++) { assert(nodes->nodeTab[0]); if (nodes->nodeTab[i]->type == XML_ELEMENT_NODE) { cur = nodes->nodeTab[i]; BFT_MALLOC((*nodes_name)[i], strlen((char *) cur->name)+1, char); strcpy((*nodes_name)[i], (char*) cur->name); } else bft_error(__FILE__, __LINE__, 0, _("The node type is not XML_ELEMENT_NODE.\nXpath: %s\n"), path); } } xmlXPathFreeObject(xpathObj); } /*---------------------------------------------------------------------------- * Return a single node's name from the xpath request. * * parameter: * path --> path for the xpath request *----------------------------------------------------------------------------*/ char* cs_gui_get_node_name(char *const path) { char **node_name = NULL; char *strvalue = NULL; int size; int i; assert(path); cs_gui_get_nodes_name(path, &node_name, &size); if ((node_name == NULL) || (size == 0)) return NULL; if (size > 1) bft_error(__FILE__, __LINE__, 0, _("Several nodes name found: %i \n" "The first one is %s \nXpath: %s\n"), size, node_name[0], path); BFT_MALLOC(strvalue, strlen(node_name[0])+1, char); strcpy(strvalue, node_name[0]); for (i=0; i3<\a>4<\a> text_name = {3,4} * * parameters: * path --> path for the xpath request * text_name <-- array of children text nodes * size <-- array size *----------------------------------------------------------------------------*/ void cs_gui_get_text_values(char *const path, char *** text_name, int *const size) { xmlXPathObjectPtr xpathObj; xmlNodeSetPtr nodes; xmlNodePtr cur; int i; assert(path); /* Evaluation de la requete */ xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx); if (xpathObj == NULL) { *size = 0; *text_name = NULL; return; } nodes = xpathObj->nodesetval; *size = (nodes) ? nodes->nodeNr : 0; if (*size == 0) *text_name = NULL; else { BFT_MALLOC(*text_name, *size, char*); for (i =0; i < *size; i++) { assert(nodes->nodeTab[0]); if (nodes->nodeTab[i]->type == XML_TEXT_NODE) { cur = nodes->nodeTab[i]; BFT_MALLOC((*text_name)[i], strlen((char *) cur->content)+1, char); strcpy((*text_name)[i], (char*) cur->content); } else /* (*text_name)[i] = NULL; */ bft_error(__FILE__, __LINE__, 0, _("The node type is not XML_TEXT_NODE.\nXpath: %s\n"), path); } } xmlXPathFreeObject(xpathObj); } /*---------------------------------------------------------------------------- * Return a single children text node from the xpath request. * * parameter: * path --> path for the xpath request *----------------------------------------------------------------------------*/ char* cs_gui_get_text_value(char *const path) { char **text_name; char *strvalue; int size; int i; assert(path); cs_gui_get_text_values(path, &text_name, &size); if ((text_name == NULL) || (size == 0)) return NULL; if (size > 1) bft_error(__FILE__, __LINE__, 0, _("Several text node found: %i \n" "The first one is %s \nXpath: %s\n"), size, text_name[0], path); BFT_MALLOC(strvalue, strlen(text_name[0])+1, char); strcpy(strvalue, text_name[0]); for (i=0; i path for the xpath request * value <-- double result of the xpath request *----------------------------------------------------------------------------*/ int cs_gui_get_double(char *const path, double *const value) { char *text_name = NULL; int test; assert(path); text_name = cs_gui_get_text_value(path); if (text_name == NULL) test = 0; else { *value = atof(text_name); BFT_FREE(text_name); test = 1; } return test; } /*---------------------------------------------------------------------------- * Modify the value parameter and return 1 if the xpath request succeeded, * otherwise just return 0. * * parameters: * path --> path for the xpath request * value <-- integer result of the xpath request *----------------------------------------------------------------------------*/ int cs_gui_get_int(char *const path, int *const value) { char *text_name = NULL; int test; assert(path); text_name = cs_gui_get_text_value(path); if (text_name == NULL) test = 0; else { *value = atoi(text_name); BFT_FREE(text_name); test = 1; } return test; } /*---------------------------------------------------------------------------- * Return the number of elements (i.e. the number of xml markups) * from a xpath request. * Example: from 3<\a>4<\a> return 2 * * parameter: * path --> path for the xpath request *----------------------------------------------------------------------------*/ int cs_gui_get_nb_element(char *const path) { xmlXPathObjectPtr xpathObj; int nb; /* Evaluation de la requete */ xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx); if (xpathObj == NULL) return 0; /* Determine l'occurence de l'element defini dans la requete path */ nb = (xpathObj->nodesetval) ? xpathObj->nodesetval->nodeNr : 0; /* Liberation de la memoire */ xmlXPathFreeObject(xpathObj); return nb; } /*---------------------------------------------------------------------------- * Return the integer max value from a list, which is a xpath request result. * Example: from 3<\a>4<\a> return 4 * * parameter: * path --> path for the xpath request *----------------------------------------------------------------------------*/ int cs_gui_get_max_value(char *const path) { xmlXPathObjectPtr xpathObj; xmlNodeSetPtr nodes; xmlNodePtr cur; int max_val=0; int size; int i; assert(path); /* Evaluation de la requete */ xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx); if (xpathObj == NULL) bft_error(__FILE__, __LINE__, 0, _("Invalid xpath: %s\n"), path); nodes=xpathObj->nodesetval; size = (nodes) ? nodes->nodeNr : 0; if (size == 0) bft_error (__FILE__, __LINE__, 0, _("No markup found: %s \n"), path); else { for (i=0; i nodeTab[i]); if(nodes->nodeTab[i]->type == XML_TEXT_NODE) { cur = nodes->nodeTab[i]; max_val = CS_MAX(max_val, atoi((char*) cur->content)); } else { bft_error(__FILE__, __LINE__, 0, _("The node type is not XML_TEXT_NODE.\nXpath: %s\n"), path); } } } xmlXPathFreeObject(xpathObj); return max_val; } /*----------------------------------------------------------------------------- * Evaluate the "status" attribute value. * Return 1 if the xpath request has succeeded, 0 otherwise. * * parameter: * path --> path for the xpath request * result <-- status="on" return 1, status="off" return 0 *----------------------------------------------------------------------------*/ int cs_gui_get_status(char *const path, int *const result) { char *status; int istatus; /* Evaluation de la requete */ status = cs_gui_get_attribute_value(path); /* Tests sur le statut */ if (status == NULL) istatus = 0; else { istatus = 1; if (cs_gui_strcmp(status, "on")) *result = 1; else if (cs_gui_strcmp(status, "off")) *result = 0; else bft_error(__FILE__, __LINE__, 0, _("Invalid attribute value: %s \nXpath: %s\n"), status, path); BFT_FREE(status); } return istatus; } /*----------------------------------------------------------------------------- * Return the number of characters needed to write an integer number * * parameter: * num --> integer number *----------------------------------------------------------------------------*/ int cs_gui_characters_number(const int num) { int i = 1; int number = 0; assert(num > 0); if (num == 0) number ++; else for (i=1; i <= num; i *= 10) number++; return number; } /*----------------------------------------------------------------------------- * Comparison between two string: return 1 if the two string are equal, 0 * otherwise. * * parameters: * s1 --> first string * s2 --> second string *----------------------------------------------------------------------------*/ int cs_gui_strcmp(const char *const s1, const char *const s2) { if (s1 == NULL || s2 == NULL) return 0; if (!strncmp(s1, s2, strlen(s1))) return 1; return 0; } /*----------------------------------------------------------------------------- * Copy a C string into a Fortran string. * * parameters: * chainef <--> Fortran string * chainc --> C string * lstrF --> maximum length of the Fortran string *----------------------------------------------------------------------------*/ void cs_gui_strcpy_c2f( char *const chainef, const char *const chainec, const int lstrF) { int i; assert(chainec != NULL); assert(lstrF > 0); strncpy(chainef, chainec, strlen(chainec)); for (i = strlen(chainec); i < lstrF ; i++) chainef[i] = ' '; } /*----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- * Stocke dans values le resultat de la requete path * Exemple pour : * 3 * 4 * stocke dans le tableau de flottant values les valeurs 3 et 4 * * retourne 0 ou le nombre de balises *----------------------------------------------------------------------------*/ /* int cs_gui_get_double_values(char *const path, double **const values) { char **text_name; int size; int i; int test = 0; cs_gui_get_text_values(path, &text_name, &size); BFT_MALLOC(*values, size, double); if (text_name == NULL) test= 0; else { for (i=0 ; i < size ; i++){ (*values)[i]=atof(text_name[i]); BFT_FREE(text_name[i]); } BFT_FREE(text_name); test = size; } return test; } */ /*----------------------------------------------------------------------------*/ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _CS_HAVE_XML */