gitktools.c

Go to the documentation of this file.
00001 
00018 #define GITK_LIB_C
00019 #define GITK_TOOLS_C
00020 
00021 #include "gitkincludes.h"
00022 
00023 
00029 static void gitk_dialog_dump_walker(xmlNodePtr cur,const gint level) {
00030   gint i;
00031   xmlChar *elem,*attr;
00032   xmlNsPtr nsptr;
00033 
00034   while(cur != NULL) {
00035     if(xmlNodeIsText(cur)) {
00036       //-- dump node contents
00037       if(!xmlIsBlankNode(cur)) {
00038         if((elem=xmlNodeGetContent(cur))) {
00039           print_ansi(ANSI_COLOR_DARKGRAY);for(i=0;i<level;i++) gitk_dump("..");
00040           gitk_dump1(ANSI_COLOR_LIGHTBLUE"%s"ANSI_COLOR_LIGHTGRAY"\n",elem);
00041           xmlFree(elem);
00042         }
00043       }
00044     }
00045     else {
00046       //-- dump node name
00047       print_ansi(ANSI_COLOR_DARKGRAY);for(i=0;i<level;i++) gitk_dump("..");
00048       nsptr=cur->ns;
00049       if(nsptr && (nsptr->prefix)) {
00050         gitk_dump2(ANSI_COLOR_WHITE"%s:%s",(xmlChar *)nsptr->prefix,cur->name);
00051       }
00052       else {
00053         gitk_dump1(ANSI_COLOR_WHITE"%s",cur->name);
00054       }
00055       /*
00056       if(!strncasecmp(cur->name,"dialog",8)) {
00057         if((attr=xmlGetProp(cur,"focus"))) {
00058           gitk_dump1(ANSI_COLOR_LIGHTRED" focus=\"%s\"",attr);
00059           xmlFree(attr);
00060         }
00061       }
00062       */
00063       if(!strncasecmp(cur->name,"widget",7)) {
00064         if((attr=xmlGetProp(cur,"id"))) {
00065           gitk_dump1(ANSI_COLOR_LIGHTRED" id=\"%s\"",attr);
00066           xmlFree(attr);
00067         }
00068         if((attr=xmlGetProp(cur,"type"))) {
00069           gitk_dump1(ANSI_COLOR_LIGHTRED" type=\"%s\"",attr);
00070           xmlFree(attr);
00071         }
00072         if((attr=xmlGetProp(cur,"hasFocus"))) {
00073           gitk_dump1(ANSI_COLOR_LIGHTRED" hasFocus=\"%s\"",attr);
00074           xmlFree(attr);
00075         }
00076       }
00077       gitk_dump(ANSI_COLOR_LIGHTGRAY"\n");
00078     }
00079     //-- recurse into node childen
00080     if(cur->children!=NULL) gitk_dialog_dump_walker(cur->children,level+1);
00081     cur = cur->next;
00082   }
00083 }
00084 
00085 
00090 void gitk_dialog_dump(xmlDocPtr const  doc) {
00091   if( (doc!=NULL)) {
00092     gitk_dialog_dump_walker(xmlDocGetRootElement(doc),0);
00093     print_ansi(ANSI_COLOR_LIGHTGRAY);
00094   }
00095   else if(doc==NULL) gitk_log("doc is empty");
00096 }
00097 
00098 
00105 xmlXPathObjectPtr gitk_xpath_type_filter(xmlXPathObjectPtr xpath_optr,const xmlXPathObjectType type) {
00106   if(xpath_optr && (xpath_optr->type!=type)) {
00107     gitk_err2("xpath expr does not returned the expected type: ist=%ld <-> soll=%ld",(unsigned long)xpath_optr->type,(unsigned long)type);
00108     xmlXPathFreeObject(xpath_optr);
00109     xpath_optr=NULL;
00110   }
00111   return(xpath_optr);
00112 }
00113 
00114 
00123 xmlXPathObjectPtr gitk__cxpath_get_object(GitkDialogPtr const dialog,GitkDialogAccessType access_type,xmlXPathCompExprPtr const xpath_comp_expression, xmlNodePtr const root_node) {
00124   xmlXPathObjectPtr result=NULL;
00125   xmlXPathContextPtr ctxt;
00126   xmlDocPtr doc;
00127 
00128   g_assert(dialog!=NULL);
00129 
00130   //gitk_log_intro();
00131   
00132   if((doc=gitk__dialog_get_doc(dialog,access_type))) {
00133     if((ctxt=xmlXPathNewContext(doc))) {
00134       if(root_node) ctxt->node=root_node;
00135       else ctxt->node=xmlDocGetRootElement(doc);
00136       if((!xmlXPathRegisterNs(ctxt,GITK_NS_PREFIX,GITK_NS_URL))
00137       && (!xmlXPathRegisterNs(ctxt,"dc","http://purl.org/dc/elements/1.1/"))) {
00138         result=xmlXPathCompiledEval(xpath_comp_expression,ctxt);
00139         xmlXPathRegisteredNsCleanup(ctxt);
00140       }
00141       else gitk_err("failed to register \"giml\" or \"dc\" namespace");
00142       xmlXPathFreeContext(ctxt);
00143     }
00144     else gitk_err("failed to get xpath context");
00145   }
00146   else gitk_err("failed to get dst doc");
00147   //gitk_log_outro();
00148   return(result);
00149 }
00150 
00151 
00160 xmlXPathObjectPtr gitk__xpath_get_object(GitkDialogPtr const dialog,GitkDialogAccessType access_type,gchar * const xpath_expression, xmlNodePtr const root_node) {
00161   xmlXPathObjectPtr result=NULL;
00162   xmlXPathCompExprPtr xpath_comp_expression;
00163 
00164   g_assert(dialog!=NULL);
00165 
00166   //-- compile xpath expression
00167   if((xpath_comp_expression=xmlXPathCompile(xpath_expression))) {
00168     result=gitk__cxpath_get_object(dialog,access_type,xpath_comp_expression,root_node);
00169   }
00170   else { gitk_err1("failed to compile xpath expression \"%s\"",xpath_expression); }
00171   return(result);
00172 }
00173 
00174 
00183 gchar *gitk__cxpath_get_string(GitkDialogPtr const dialog,GitkDialogAccessType access_type,xmlXPathCompExprPtr const xpath_comp_expression, xmlNodePtr const root_node) {
00184   gchar *result=NULL;
00185   xmlXPathObjectPtr xpath_optr;
00186 
00187   //-- evaluate xpath expression
00188   if((xpath_optr=gitk__cxpath_get_object(dialog,access_type,xpath_comp_expression,root_node))) {
00189     xpath_optr=xmlXPathConvertString(xpath_optr);
00190     //gitk_log2("stringval=0x%08lx \"%s\"",(unsigned long)xpath_optr->stringval,xpath_optr->stringval);
00191     result=strdup(xmlXPathCastToString(xpath_optr));
00192     xmlXPathFreeObject(xpath_optr);
00193   }
00194   else gitk_err("failed to eval xpath expr");
00195   return(result);
00196 }
00197 
00198 
00207 gchar *gitk__xpath_get_string(GitkDialogPtr const dialog,GitkDialogAccessType access_type,gchar * const xpath_expression, xmlNodePtr const root_node) {
00208   gchar *result=NULL;
00209   xmlXPathCompExprPtr xpath_comp_expression;
00210 
00211   //-- compile xpath expression
00212   if((xpath_comp_expression=xmlXPathCompile(xpath_expression))) {
00213     result=gitk__cxpath_get_string(dialog,access_type,xpath_comp_expression,root_node);
00214     xmlXPathFreeCompExpr(xpath_comp_expression);
00215   }
00216   else { gitk_err1("failed to compile xpath expression \"%s\"",xpath_expression); }
00217   return(result);
00218 }
00219 
00220 
00229 xmlNodePtr gitk__cxpath_get_node(GitkDialogPtr const dialog,GitkDialogAccessType access_type,xmlXPathCompExprPtr const xpath_comp_expression, xmlNodePtr const root_node) {
00230   xmlNodePtr node=NULL;
00231   xmlXPathObjectPtr xpath_optr;
00232 
00233   //gitk_log_intro();
00234 
00235   //-- evaluate xpath expression
00236   if((xpath_optr=gitk_xpath_type_filter(
00237       gitk__cxpath_get_object(dialog,access_type,xpath_comp_expression,root_node),
00238       XPATH_NODESET))) {
00239     const xmlNodeSetPtr ns=(xmlNodeSetPtr)xpath_optr->nodesetval;
00240     //-- has it exactly one child
00241     if(xmlXPathNodeSetGetLength(ns)==1) {
00242       node=xmlXPathNodeSetItem(ns,0);
00243     }
00244     else { gitk_log1("nodeset should contain exactly one node (but has %d nodes)",xmlXPathNodeSetGetLength(ns)); }
00245     xmlXPathFreeObject(xpath_optr);
00246   }
00247   else { gitk_err("failed to eval xpath expr"); }
00248   //gitk_log_outro();
00249   return(node);
00250 }
00251 
00252 
00261 xmlNodePtr gitk__xpath_get_node(GitkDialogPtr const dialog,GitkDialogAccessType access_type,gchar * const xpath_expression, xmlNodePtr const root_node) {
00262   xmlXPathCompExprPtr xpath_comp_expression;
00263   xmlNodePtr node=NULL;
00264   
00265   //-- compile xpath expression
00266   if((xpath_comp_expression=xmlXPathCompile(xpath_expression))) {
00267     node=gitk__cxpath_get_node(dialog,access_type,xpath_comp_expression,root_node);
00268     xmlXPathFreeCompExpr(xpath_comp_expression);
00269   }
00270   else { gitk_err1("failed to compile xpath expression \"%s\"",xpath_expression); }
00271   return(node);
00272 }
00273 
00274 
00279 gchar *gitk_get_widget_xpath_expression(const gchar * const widget_id) {
00280   static gchar qstr[100+GITK_CONTROL_ID_MAXLEN];
00281   gint sl;
00282    
00283   sl=strlen(widget_id);
00284   snprintf(qstr,99+GITK_CONTROL_ID_MAXLEN,"//"GITK_NS_PREFIX":widget[@id=\"%s\"]",widget_id);
00285   return(qstr);
00286 }
00287 
00288 
00294 gchar *gitk_get_widget_child_xpath_expression(const gchar * const widget_id,const gchar * const widget_value) {
00295   static gchar qstr[100+GITK_CONTROL_ID_MAXLEN];
00296   gint sl;
00297 
00298   sl=strlen(widget_id)+strlen(widget_value);
00299   snprintf(qstr,99+GITK_CONTROL_ID_MAXLEN,"//"GITK_NS_PREFIX":widget[@id=\"%s\"]/"GITK_NS_PREFIX":%s",widget_id,widget_value);
00300   return(qstr);
00301 }
00302 
00303 
00311 void gitk_dialog_safe_new_child(xmlNsPtr const ns,xmlNodePtr const parent,gchar * const name,gchar * const content) {
00312   xmlNodePtr cur;
00313   gboolean already_exists=FALSE;
00314 
00315   if((cur=parent->children)!=NULL) {
00316     while(cur) {
00317       if(!xmlNodeIsText(cur) && !strcasecmp(cur->name,name)) {
00318         already_exists=TRUE;
00319         break;
00320       }
00321       cur=cur->next;
00322     }
00323   }
00324   if(!already_exists) {
00325     xmlNewChild(parent,ns,name,content);
00326   }
00327 }
00328 
00329 
00337 char *parse_commandline_arg(guint * const argc, gchar *** const argv, guint * const i, gchar * const argn) {
00338   gchar *arg;
00339   gchar *argn2;
00340   guint argn2l;
00341 
00342   gitk_log2("%s(\"%s\") beg",__FUNCTION__,argn);
00343   
00344   g_assert(argc!=NULL);
00345   g_assert(argv!=NULL);
00346   g_assert(i!=NULL);
00347   g_assert(argn!=NULL);
00348   g_assert(((*argv)[*i])!=NULL);
00349 
00350   argn2l=strlen(argn);
00351   argn2=alloca(argn2l+2);
00352   strcpy(argn2,argn);
00353   strcat(argn2,"=");
00354 
00355   if(!strcmp(argn,(*argv)[*i]) || !strncmp(argn2,(*argv)[*i],argn2l+1)) {
00356     gitk_log("  matches, now extract arg");
00357     arg=(*argv)[*i]+argn2l;
00358       
00359     if(*arg=='=') arg++;      // there is an '=' or '\0'
00360     else if((*i)+1<*argc) {
00361       (*argv)[*i] = NULL;
00362       (*i)++;
00363       arg=(*argv)[*i];
00364     }
00365     else {
00366       gitk_log1("%s()=null end",__FUNCTION__);
00367       return(NULL);
00368     }
00369     gitk_log("  discarding parameter");
00370     (*argv)[*i]=NULL;
00371     gitk_log("  found something");
00372     if(arg && *arg) {
00373       gitk_log1("%s()=arg end",__FUNCTION__);
00374       return(arg);
00375     }
00376   }
00377   gitk_log1("%s()=null end",__FUNCTION__);
00378   return(NULL);
00379 }
00380 
00381 
00387 void cleanup_commandline_args(guint * const argc, gchar *** const argv) {
00388   guint i,j,k;
00389 
00390   for (i = 1; i < *argc; i++) {
00391     for (k = i; k < *argc; k++) {
00392       if ((*argv)[k] != NULL) break;
00393     }
00394     if (k > i) {
00395       k -= i;
00396       for (j = i + k; j < *argc; j++) {
00397         (*argv)[j-k] = (*argv)[j];
00398       }
00399       *argc -= k;
00400     }
00401   }
00402 }
00403 
00408 int gitk_puts(const char *utf8) {
00409   gchar *loc,*cs;
00410   int res;
00411 
00412   #ifdef ENABLE_NLS
00413     cs=nl_langinfo(CODESET);
00414   #else
00415     cs="ISO-8859-1";
00416   #endif
00417   loc=g_convert(utf8,-1,cs,"UTF-8",NULL,NULL,NULL);
00418   res=puts(loc);
00419   g_free(loc);
00420   return(res);
00421 }
00422 
00428 int gitk_printf(const char *utf8,...) {
00429   gchar *loc,*cs;
00430   va_list args;
00431   int res;
00432   
00433   #ifdef ENABLE_NLS
00434     cs=nl_langinfo(CODESET);
00435   #else
00436     cs="ISO-8859-1";
00437   #endif
00438   loc=g_convert(utf8,-1,cs,"UTF-8",NULL,NULL,NULL);
00439   va_start(args,utf8);
00440   res=vprintf(loc,args);
00441   va_end(args);
00442   g_free(loc);
00443   return(res);
00444 }

Generated on Thu Oct 28 10:59:15 2004 for gitk by doxygen 1.3.6