Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

utils.c

Go to the documentation of this file.
00001 /*
00002 *This file is part of GNU MlView
00003 *
00004 *GNU MlView is free software; you can redistribute it and/or modify it under the terms of 
00005 *the GNU General Public License as published by the Free Software Foundation; either version 2, 
00006 *or (at your option) any later version.
00007 *
00008 *GNU MlView is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
00009 *without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00010 *See the GNU General Public License for more details.
00011 *
00012 *You should have received a copy of the GNU General Public License along with MlView; 
00013 *see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00014 *
00015 *
00016 *Copyright 2001 dodji seketeli
00017 */
00018 
00019 
00020 #include <stdio.h>
00021 #include <locale.h>
00022 #include <ctype.h>
00023 #include "utils.h"
00024 #include <gnome.h>
00025 #include "config.h"
00026 #include <libxml/valid.h>
00027 
00028 typedef struct _ErrorMessage ErrorMessage ;
00029 
00030 struct _ErrorMessage{
00031   gchar * error_type ;
00032   gchar *error_string ;
00033 };
00034 
00035 static ErrorMessage p_error_messages_tab[]={
00036   {"error","OK"}, /*0*/
00037   {"error","parser internal error"},
00038   {"error","no more memory"},
00039   {"error","error at document start"}, /*3*/
00040   {"error","document empty"},
00041   {"error","document end reached unexpectedly"},
00042   {"error","invalid hexadecimal character reference"}, /*6*/
00043   {"error","invalid decimal character reference"},
00044   {"error","invalid chararacter reference"},
00045   {"error","invalid character"},
00046   {"error","character reference at end of file"}, /*10*/
00047   {"error","character reference in prolog"},
00048   {"error","character reference in epilog"}, /*12*/
00049   {"error","character reference in DTD"},
00050   {"error","entity reference at end of file"}, /*14*/
00051   {"error","entity reference in prolog"},
00052   {"error","entity reference in epilog"}, /*16*/
00053   {"error","entity reference in DTD"},
00054   {"error","pe reference at end of file"}, /*18*/
00055   {"error","pe reference in prolog"},
00056   {"error","pe reference in epilog"}, /*20*/
00057   {"error","pe reference in int subset"},
00058   {"error","entity reference with no name"}, /*22*/
00059   {"error","entity reference with semicolon missing"},
00060   {"error","pe reference with no name"}, /*24*/
00061   {"error","pe reference semicolon missing"},
00062   {"error","undeclared entity"}, /*26*/
00063   {"warning","undeclared entity"},
00064   {"error","unparsed entity"}, /*28*/
00065   {"error","entity is external"},
00066   {"error","entity is parameter"},/*30*/
00067   {"error","unknown encoding"},
00068   {"error","unsupported encoding"}, /*32*/
00069   {"error","string not started"},
00070   {"error","string not closed"}, /*34*/
00071   {"error","namespace declaration error"},
00072   {"error","entity not started"} , /*36*/
00073   {"error","entity not finished"},
00074 
00075   {"error","\'<\' character in attribute"}, /*38*/
00076   {"error","attribute not started"},
00077   {"error","entity not finished"}, /*40*/
00078   {"error","attribute without value"}, 
00079   {"error","attribute redefined"},/*42*/
00080   {"error","literal not started"},
00081   {"error","literal not finished"}, /*44*/
00082   {"error","comment not finished"},
00083   {"error","processing instruction not started"}, /*46*/
00084   {"error","processing instruction not finished"},
00085   {"error","notation not started"}, /*48*/
00086   {"error","notation not finished"},
00087   {"error","attribute list not star*ted"}, /*50*/
00088   {"error","attribute list not finished"},
00089   {"error","mixed content not started"}, /*52*/
00090   {"error","mixed content not finished"},
00091   {"error","element content not started"}, /*54*/
00092   {"error","element content not finished"},
00093   {"error","xml declaration not started"},/*56*/
00094   {"error","xml declaration not finished"},
00095   {"error","condition section not started"},/*58*/
00096   {"error","condition section not finished"},
00097   {"error","external subset not finished"},/*60*/
00098   {"error","doctype not finished"},
00099   {"error","misplaced CDATA end"},/*62*/
00100   {"error","CDATA not finished"},
00101   {"error","reserved xml name"},/*64*/
00102   {"error","space required"},
00103   {"error","separator required"}, /*66*/
00104   {"error","NM token required"},
00105   {"error","name token required"}, /*68*/
00106   {"error","PCDATA required"},
00107   {"error","URI required"},/*70*/
00108   {"error","public id required"},
00109   {"error","\'<\' required"}, /*72*/
00110   {"error","\'>\' required"},
00111   {"error","\'</\' required"},/*74*/
00112   {"error","\'=\' required"},
00113   {"error","tag name mismatch"}, /*76*/
00114   {"error","tag not finished"},
00115   {"error","standalone value"},/*78*/
00116   {"error","encoding name"},
00117   {"error","hyphen in comment"},/*80*/
00118   {"error","invalid encoding"},
00119   {"error","entity standalone"},/*82*/
00120   {"error","condition section invalid"},
00121   {"error","value required"},/*84*/
00122   {"error","not well balanced"},
00123   {"error","extra content"},/*86*/
00124   {"error","entity character error"},
00125   {"error","PE internal"},/*88*/
00126   {"error","entity loop"},
00127   {"error","entity boundary"},/*90*/
00128   {"error","invalid uri"},
00129   {"error","uri fragment"},/*92*/  
00130   {NULL}
00131 } ;
00132 
00133 /*
00134  *xmlParserErrors messages retrieval routines.
00135  */
00136 
00146 void get_xml_parser_error_as_string1(xmlParserCtxtPtr a_xml_parser_context, gchar * a_error_string){
00147   ErrorMessage error_message ;
00148   g_return_if_fail(a_xml_parser_context!=NULL) ;
00149 
00150   a_error_string=NULL ;    
00151   
00152   if(a_xml_parser_context->errNo >= sizeof(p_error_messages_tab)-1)
00153     return ;
00154   error_message=p_error_messages_tab[a_xml_parser_context->errNo] ;
00155   
00156   a_error_string=g_malloc(strlen(error_message.error_type) + 
00157                          strlen(error_message.error_string) + 2) ;
00158   sprintf(a_error_string, "%s:%s",error_message.error_type,error_message.error_string) ;
00159 }
00160 
00170 void get_xml_parser_error_as_string2(xmlParserErrors a_xml_error, gchar * a_error_string){
00171   ErrorMessage error_message ;
00172   a_error_string=NULL ;  
00173   
00174   if(a_xml_error >= sizeof(p_error_messages_tab) -1)
00175     return ;
00176   error_message=error_message=p_error_messages_tab[a_xml_error] ;
00177   a_error_string=g_malloc(strlen(error_message.error_type) + 
00178                          strlen(error_message.error_string) + 2) ;
00179   sprintf(a_error_string, "%s:%s",error_message.error_type,error_message.error_string) ;
00180 }
00181 
00182 gboolean
00183 utils_is_white_string(const gchar *a_str)
00184 {
00185         gchar * tmp_str= (gchar *) a_str ;
00186         if(tmp_str == NULL)
00187                 return FALSE ;  
00188 
00189         while(*tmp_str){
00190                 if(!isspace(*tmp_str)) return FALSE ;                   
00191                 tmp_str ++ ;
00192         }
00193         return TRUE ;
00194 }
00195 
00196 void
00197 init_i18n (void) 
00198 {
00199         setlocale (LC_ALL, "") ;
00200         bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR) ;
00201         textdomain (PACKAGE) ;
00202 }
00203 
00204 /*=============================================
00205   some usefull patches to libxml:
00206 
00207   xmlUnlinkNs (xmlNode * node, xmlNs * ns)
00208   xmlUnlinkNsDef (xmlNode * node, xmlNs * ns)
00209  *============================================*/
00210 xmlNs *
00211 xmlUnlinkNs (xmlNode * node, xmlNs * ns)
00212 {
00213         xmlNs * cur ;
00214         
00215         if(node == NULL  ||  ns == NULL) {
00216                 return NULL;
00217         }
00218 
00219         cur = node->ns ;
00220         if(cur == NULL)
00221                 return NULL ;
00222 
00223         /*Check if the namespace to unlink is the first ns in the xml node nsDef list. If yes, unlink it*/
00224         if(ns == cur){
00225                 node->nsDef = node->nsDef->next ;
00226                 ns->next = NULL ;
00227                 return ns ;
00228         }
00229 
00230         /*the namespace to unlink may be further in the ns list. Walk to the namespace just before it...*/
00231         while(cur != NULL  &&  cur->next != ns) {
00232                 cur = cur->next ;
00233         }
00234         if(cur == NULL)
00235                 return NULL ;
00236 
00237         /*at this stage, cur points to the namespace that is just before the namespace to unlink. Let's now unlink ns*/
00238         if(ns->next == NULL)
00239                 cur->next = NULL ;
00240         else{
00241                 cur->next = ns->next ;
00242                 ns->next = NULL ;
00243         }
00244         return ns ;
00245         
00246 }
00247 
00248 xmlNs *
00249 xmlUnlinkNsDef (xmlNode * node, xmlNs * ns)
00250 {
00251         xmlNs * cur ;
00252 
00253         if(node == NULL  ||  ns == NULL) {
00254                 return NULL;
00255         }
00256         
00257         cur = node->nsDef ;
00258         if(cur == NULL)
00259                 return NULL ;
00260 
00261         /*Check if the namespace to unlink is the first ns in the xml node nsDef list. If yes, unlink it*/
00262         if(ns == cur){
00263                 node->nsDef = node->nsDef->next ;
00264                 ns->next = NULL ;
00265                 return ns ;
00266         }
00267 
00268         /*the namespace to unlink may be further in the ns list. Walk to the namespace just before it...*/
00269         while(cur != NULL  &&  cur->next != ns) {
00270                 cur = cur->next ;
00271         }
00272         if(cur == NULL)
00273                 return NULL ;
00274 
00275         /*at this stage, cur points to the namespace that is just before the namespace to unlink. Let's now unlink ns*/
00276         if(ns->next == NULL)
00277                 cur->next = NULL ;
00278         else{
00279                 cur->next = ns->next ;
00280                 ns->next = NULL ;
00281         }
00282         return ns ;
00283 }
00284 
00298 int
00299 xmlValidGetValidElementsChildren (xmlNode *a_node, 
00300                                   const xmlChar **a_list,
00301                                   int a_max)
00302 {
00303         xmlElement * element_desc = NULL ;
00304         gint nb_valid_elements = 0 ;
00305 
00306         /*some sanity checks...*/
00307         if (a_node == NULL) return -2 ;
00308         if (a_list == NULL) return -2 ;
00309         if (a_list == NULL)  return -2 ;
00310         if (a_max == 0) return -2 ;
00311         if (a_node->type != XML_ELEMENT_NODE) return -2 ;
00312         if (a_node->parent == NULL) return -2 ;
00313 
00314         if (a_node->children) {
00315                 /*the node is the root node 
00316                  *and it has children. We can it valid children
00317                  *with the function
00318                  */
00319                 return xmlValidGetValidElements (a_node->last, NULL, 
00320                                                  a_list, a_max) ;
00321         
00322         } else {
00323                 gint nb_elements = 0, i = 0 ;
00324                 const xmlChar * elements[256] ;
00325                 xmlNode * test_node = NULL ;
00326                 xmlValidCtxt vctxt ;
00327                 
00328                 memset(&vctxt, 0, sizeof (xmlValidCtxt));
00329 
00330                 element_desc = xmlGetDtdElementDesc(a_node->parent->doc->intSubset,
00331                                                     a_node->name);
00332                 if ((element_desc == NULL) && (a_node->parent->doc->extSubset != NULL))
00333                         element_desc = xmlGetDtdElementDesc(a_node->parent->doc->extSubset,
00334                                                             a_node->name) ;
00335                 if (element_desc == NULL) return (-1) ;
00336                 
00337                 /*
00338                  *Create a dummy child element
00339                  */
00340                 test_node = 
00341                         xmlNewChild (a_node, NULL, "<!dummy?>", NULL) ;
00342 
00343                 /*
00344                  *Insert each potential child node and check if the current node is still valid.
00345                  */
00346                 nb_elements = 
00347                         xmlValidGetPotentialChildren (element_desc->content,
00348                                                       elements, &nb_elements, 256) ;
00349                 
00350                 for (i = 0 ; i < nb_elements ; i++) {
00351                         test_node->name = elements[i] ;
00352                         if (xmlStrEqual(test_node->name, "#PCDATA"))
00353                                 test_node->type = XML_TEXT_NODE ;
00354                         else
00355                                 test_node->type = XML_ELEMENT_NODE ;
00356 
00357                         if (xmlValidateOneElement (&vctxt, a_node->parent->doc, a_node)) {
00358                                 int j ;
00359                                 for (j = 0 ; j < nb_valid_elements ; j++)
00360                                         if (xmlStrEqual (elements[i], a_list[j])) break ;
00361                                 a_list[nb_valid_elements++] = elements[i] ;
00362                                 
00363                                 if (nb_valid_elements >= a_max) break ;
00364                         }
00365                 }
00366 
00367                 /*
00368                  *Restore the tree structure
00369                  */
00370                 xmlUnlinkNode (test_node) ;
00371                 
00372                 return nb_valid_elements ;
00373         }
00374 }
00375 
00386 void
00387 utils_parse_full_name (xmlNode *a_node, gchar *a_full_name, xmlNs ** a_ns, gchar **a_local_name)
00388 {
00389         gchar *colon_ptr, *prefix, *local_name ;
00390         gchar **full_name_array ;
00391         xmlNs * ns ;
00392 
00393         g_return_if_fail(a_node != NULL) ;
00394         g_return_if_fail(a_full_name != NULL) ;
00395 
00396         *a_ns = NULL ;
00397         *a_local_name = NULL ;
00398 
00399         colon_ptr = index(a_full_name, ':') ;
00400 
00401         if(colon_ptr != NULL){
00402                 full_name_array = g_strsplit(a_full_name,":", 2) ;
00403                 prefix = full_name_array[0] ;
00404                 local_name = full_name_array[1] ;
00405                 ns = xmlSearchNs(a_node->doc,
00406                                  a_node,
00407                                  prefix) ;
00408                 if(ns != NULL)
00409                         *a_ns = ns ;
00410                 else
00411                         *a_ns = NULL ;
00412                 if(local_name != NULL && !utils_is_white_string(local_name))
00413                         *a_local_name = g_strstrip(local_name) ;
00414                 
00415         }else{
00416                 *a_local_name = g_strdup(g_strstrip(a_full_name)) ;
00417         }
00418 }
00419 
00420 /*=============================================
00421   some usefull patches i wrote for the files gtkclist.c and gtkctree.c:
00422 
00423   gtk_clist_absolute_row_top_ypixel(GtkCList *a_clist, gint a_row)
00424   gtk_ctree_node_absolute_top_ypixel(GtkCTree * a_tree, GtkCTreeNode *a_node)
00425  *============================================*/
00426 
00427 #define CELL_SPACING 1
00428 
00429 gint
00430 gtk_clist_absolute_row_top_ypixel(GtkCList *a_clist, gint a_row)
00431 {
00432         g_return_val_if_fail(a_clist != NULL,-1) ;
00433         g_return_val_if_fail(GTK_IS_CLIST(a_clist), -1) ;
00434 
00435         return (a_clist->row_height * a_row  +
00436                 (a_row + 1) * CELL_SPACING) ;
00437 }
00438 
00439 gint
00440 gtk_ctree_node_absolute_top_ypixel(GtkCTree * a_tree, GtkCTreeNode *a_node)
00441 {
00442         gint pos ;
00443         g_return_val_if_fail(a_tree != NULL, -1) ;
00444         g_return_val_if_fail(GTK_IS_CTREE(a_tree), -1) ;
00445         g_return_val_if_fail(a_node != NULL, -1) ;
00446 
00447         pos = g_list_position(a_tree->clist.row_list,&a_node->list) ;
00448         return gtk_clist_absolute_row_top_ypixel(&a_tree->clist, pos) ;
00449 }

Generated on Sat Jul 6 09:57:38 2002 for Gnome-MlView by doxygen1.2.16