Jabber WindowGram Client (JWGC)

Introduction Screenshots Installation Downloads
Documentation Browse Source Resources Project Site

Stable Version
-none-

Latest Version
beta5



Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

xode.c

Go to the documentation of this file.
00001 /*
00002  *  This program is free software; you can redistribute it and/or modify
00003  *  it under the terms of the GNU General Public License as published by
00004  *  the Free Software Foundation; either version 2 of the License, or
00005  *  (at your option) any later version.
00006  *
00007  *  This program is distributed in the hope that it will be useful,
00008  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00009  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010  *  GNU General Public License for more details.
00011  *
00012  *  You should have received a copy of the GNU General Public License
00013  *  along with this program; if not, write to the Free Software
00014  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00015  *
00016  *  Jabber
00017  *  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
00018  */
00019 
00020 #include "libxode.h"
00021 
00022 static int _xode_strcmp(const char *a, const char *b)
00023 {
00024     if(a == NULL || b == NULL) return -1;
00025 
00026     return strcmp(a,b);
00027 }
00028 
00029 /* Internal routines */
00030 static xode _xode_new(xode_pool p, const char* name, unsigned int type)
00031 {
00032     xode result = NULL;
00033     if (type > XODE_TYPE_LAST)
00034         return NULL;
00035 
00036     if (type != XODE_TYPE_CDATA && name == NULL)
00037         return NULL;
00038 
00039     if (p == NULL)
00040     {
00041         p = xode_pool_heap(1*1024);
00042     }
00043 
00044     /* Allocate & zero memory */
00045     result = (xode)xode_pool_malloc(p, sizeof(_xode));
00046     memset(result, '\0', sizeof(_xode));
00047 
00048     /* Initialize fields */
00049     if (type != XODE_TYPE_CDATA)
00050         result->name = xode_pool_strdup(p,name);
00051     result->type = type;
00052     result->p = p;
00053     return result;
00054 }
00055 
00056 static xode _xode_appendsibling(xode lastsibling, const char* name, unsigned int type)
00057 {
00058     xode result;
00059 
00060     result = _xode_new(xode_get_pool(lastsibling), name, type);
00061     if (result != NULL)
00062     {
00063         /* Setup sibling pointers */
00064         result->prev = lastsibling;
00065         lastsibling->next = result;
00066     }
00067     return result;
00068 }
00069 
00070 static xode _xode_insert(xode parent, const char* name, unsigned int type)
00071 {
00072     xode result;
00073 
00074     if(parent == NULL || name == NULL) return NULL;
00075 
00076     /* If parent->firstchild is NULL, simply create a new node for the first child */
00077     if (parent->firstchild == NULL)
00078     {
00079         result = _xode_new(parent->p, name, type);
00080         parent->firstchild = result;
00081     }
00082     /* Otherwise, append this to the lastchild */
00083     else
00084     {
00085         result= _xode_appendsibling(parent->lastchild, name, type);
00086     }
00087     result->parent = parent;
00088     parent->lastchild = result;
00089     return result;
00090 
00091 }
00092 
00093 static xode _xode_search(xode firstsibling, const char* name, unsigned int type)
00094 {
00095     xode current;
00096 
00097     /* Walk the sibling list, looking for a XODE_TYPE_TAG xode with
00098     the specified name */
00099     current = firstsibling;
00100     while (current != NULL)
00101     {
00102         if (name != NULL && (current->type == type) && (_xode_strcmp(current->name, name) == 0))
00103             return current;
00104         else
00105             current = current->next;
00106     }
00107     return NULL;
00108 }
00109 
00110 static char* _xode_merge(xode_pool p, char* dest, unsigned int destsize, const char* src, unsigned int srcsize)
00111 {
00112     char* result;
00113     result = (char*)xode_pool_malloc(p, destsize + srcsize + 1);
00114     memcpy(result, dest, destsize);
00115     memcpy(result+destsize, src, srcsize);
00116     result[destsize + srcsize] = '\0';
00117 
00118     /* WARNING: major ugly hack: since we're throwing the old data away, let's jump in the xode_pool and subtract it from the size, this is for xmlstream's big-node checking */
00119     p->size -= destsize;
00120 
00121     return result;
00122 }
00123 
00124 static void _xode_hidesibling(xode child)
00125 {
00126     if(child == NULL)
00127         return;
00128 
00129     if(child->prev != NULL)
00130         child->prev->next = child->next;
00131     if(child->next != NULL)
00132         child->next->prev = child->prev;
00133 }
00134 
00135 static void _xode_tag2str(xode_spool s, xode node, int flag)
00136 {
00137     xode tmp;
00138 
00139     if(flag==0 || flag==1)
00140     {
00141             xode_spooler(s,"<",xode_get_name(node),s);
00142             tmp = xode_get_firstattrib(node);
00143             while(tmp) {
00144                 xode_spooler(s," ",xode_get_name(tmp),"='",xode_strescape(xode_get_pool(node),xode_get_data(tmp)),"'",s);
00145                 tmp = xode_get_nextsibling(tmp);
00146             }
00147             if(flag==0)
00148                 xode_spool_add(s,"/>");
00149             else
00150                 xode_spool_add(s,">");
00151     }
00152     else
00153     {
00154             xode_spooler(s,"</",xode_get_name(node),">",s);
00155     }
00156 }
00157 
00158 static xode_spool _xode_tospool(xode node)
00159 {
00160     xode_spool s;
00161     int level=0,dir=0;
00162     xode tmp;
00163 
00164     if(!node || xode_get_type(node) != XODE_TYPE_TAG)
00165         return NULL;
00166 
00167     s = xode_spool_newfrompool(xode_get_pool(node));
00168     if(!s) return(NULL);
00169 
00170     while(1)
00171     {
00172         if(dir==0)
00173         {
00174             if(xode_get_type(node) == XODE_TYPE_TAG)
00175             {
00176                         if(xode_has_children(node))
00177                 {
00178                             _xode_tag2str(s,node,1);
00179                             node = xode_get_firstchild(node);
00180                             level++;
00181                             continue;
00182                         }
00183                 else
00184                 {
00185                             _xode_tag2str(s,node,0);
00186                         }
00187                 }
00188             else
00189             {
00190                         xode_spool_add(s,xode_strescape(xode_get_pool(node),xode_get_data(node)));
00191                 }
00192             }
00193 
00194         tmp = xode_get_nextsibling(node);
00195             if(!tmp)
00196         {
00197                 node = xode_get_parent(node);
00198                 level--;
00199                 if(level>=0) _xode_tag2str(s,node,2);
00200                 if(level<1) break;
00201                 dir = 1;
00202             }
00203         else
00204         {
00205                 node = tmp;
00206                 dir = 0;
00207             }
00208     }
00209 
00210     return s;
00211 }
00212 
00213 
00214 /* External routines */
00215 
00216 
00217 /*
00218  *  xode_new_tag -- create a tag node
00219  *  Automatically creates a memory xode_pool for the node.
00220  *
00221  *  parameters
00222  *      name -- name of the tag
00223  *
00224  *  returns
00225  *      a pointer to the tag node
00226  *      or NULL if it was unsuccessfull
00227  */
00228 xode xode_new(const char* name)
00229 {
00230     return _xode_new(NULL, name, XODE_TYPE_TAG);
00231 }
00232 
00233 
00234 /*
00235  *  xode_new_tag_pool -- create a tag node within given pool
00236  *
00237  *  parameters
00238  *      p -- previously created memory pool
00239  *      name -- name of the tag
00240  *
00241  *  returns
00242  *      a pointer to the tag node
00243  *      or NULL if it was unsuccessfull
00244  */
00245 xode xode_new_frompool(xode_pool p, const char* name)
00246 {
00247     return _xode_new(p, name, XODE_TYPE_TAG);
00248 }
00249 
00250 
00251 /*
00252  *  xode_insert_tag -- append a child tag to a tag
00253  *
00254  *  parameters
00255  *      parent -- pointer to the parent tag
00256  *      name -- name of the child tag
00257  *
00258  *  returns
00259  *      a pointer to the child tag node
00260  *      or NULL if it was unsuccessfull
00261  */
00262 xode xode_insert_tag(xode parent, const char* name)
00263 {
00264     return _xode_insert(parent, name, XODE_TYPE_TAG);
00265 }
00266 
00267 
00268 /*
00269  *  xode_insert_cdata -- append character data to a tag
00270  *  If last child of the parent is CDATA, merges CDATA nodes. Otherwise
00271  *  creates a CDATA node, and appends it to the parent's child list.
00272  *
00273  *  parameters
00274  *      parent -- parent tag
00275  *      CDATA -- character data
00276  *      size -- size of CDATA
00277  *              or -1 for null-terminated CDATA strings
00278  *
00279  *  returns
00280  *      a pointer to the child CDATA node
00281  *      or NULL if it was unsuccessfull
00282  */
00283 xode xode_insert_cdata(xode parent, const char* CDATA, unsigned int size)
00284 {
00285     xode result;
00286 
00287     if(CDATA == NULL || parent == NULL)
00288         return NULL;
00289 
00290     if(size == -1)
00291         size = strlen(CDATA);
00292 
00293     if ((parent->lastchild != NULL) && (parent->lastchild->type == XODE_TYPE_CDATA))
00294     {
00295         result = parent->lastchild;
00296         result->data = _xode_merge(result->p, result->data, result->data_sz, CDATA, size);
00297         result->data_sz = result->data_sz + size;
00298     }
00299     else
00300     {
00301         result = _xode_insert(parent, "", XODE_TYPE_CDATA);
00302         if (result != NULL)
00303         {
00304             result->data = (char*)xode_pool_malloc(result->p, size + 1);
00305             memcpy(result->data, CDATA, size);
00306             result->data[size] = '\0';
00307             result->data_sz = size;
00308         }
00309     }
00310 
00311     return result;
00312 }
00313 
00314 
00315 /*
00316  *  xode_gettag -- find given tag in an xode tree
00317  *
00318  *  parameters
00319  *      parent -- pointer to the parent tag
00320  *      name -- "name" for the child tag of that name
00321  *              "name/name" for a sub child (recurses)
00322  *              "?attrib" to match the first tag with that attrib defined
00323  *              "?attrib=value" to match the first tag with that attrib and value
00324  *              or any combination: "name/name/?attrib", etc
00325  *
00326  *  results
00327  *      a pointer to the tag matching search criteria
00328  *      or NULL if search was unsuccessfull
00329  */
00330 xode xode_get_tag(xode parent, const char* name)
00331 {
00332     char *str, *slash, *qmark, *equals;
00333     xode step, ret;
00334 
00335     if(parent == NULL || parent->firstchild == NULL || name == NULL || name == '\0') return NULL;
00336 
00337     if(strstr(name, "/") == NULL && strstr(name,"?") == NULL)
00338         return _xode_search(parent->firstchild, name, XODE_TYPE_TAG);
00339 
00340     /* jer's note: why can't I modify the name directly, why do I have to strdup it?  damn c grrr! */
00341     str = strdup(name);
00342     slash = strstr(str, "/");
00343     qmark = strstr(str, "?");
00344     equals = strstr(str, "=");
00345 
00346     if(qmark != NULL && (slash == NULL || qmark < slash))
00347     { /* of type ?attrib */
00348 
00349         *qmark = '\0';
00350         qmark++;
00351         if(equals != NULL)
00352         {
00353             *equals = '\0';
00354             equals++;
00355         }
00356 
00357         for(step = parent->firstchild; step != NULL; step = xode_get_nextsibling(step))
00358         {
00359             if(xode_get_type(step) != XODE_TYPE_TAG)
00360                 continue;
00361 
00362             if(*str != '\0')
00363                 if(_xode_strcmp(xode_get_name(step),str) != 0)
00364                     continue;
00365 
00366             if(xode_get_attrib(step,qmark) == NULL)
00367                 continue;
00368 
00369             if(equals != NULL && _xode_strcmp(xode_get_attrib(step,qmark),equals) != 0)
00370                 continue;
00371 
00372             break;
00373         }
00374 
00375         free(str);
00376         return step;
00377     }
00378 
00379 
00380     *slash = '\0';
00381     ++slash;
00382 
00383     for(step = parent->firstchild; step != NULL; step = xode_get_nextsibling(step))
00384     {
00385         if(xode_get_type(step) != XODE_TYPE_TAG) continue;
00386 
00387         if(_xode_strcmp(xode_get_name(step),str) != 0)
00388             continue;
00389 
00390         ret = xode_get_tag(step, slash);
00391         if(ret != NULL)
00392         {
00393             free(str);
00394             return ret;
00395         }
00396     }
00397 
00398     free(str);
00399     return NULL;
00400 }
00401 
00402 
00403 /* return the cdata from any tag */
00404 char *xode_get_tagdata(xode parent, const char *name)
00405 {
00406     xode tag;
00407 
00408     tag = xode_get_tag(parent, name);
00409     if(tag == NULL) return NULL;
00410 
00411     return xode_get_data(tag);
00412 }
00413 
00414 
00415 void xode_put_attrib(xode owner, const char* name, const char* value)
00416 {
00417     xode attrib;
00418 
00419     if(owner == NULL || name == NULL || value == NULL) return;
00420 
00421     /* If there are no existing attributs, allocate a new one to start
00422     the list */
00423     if (owner->firstattrib == NULL)
00424     {
00425         attrib = _xode_new(owner->p, name, XODE_TYPE_ATTRIB);
00426         owner->firstattrib = attrib;
00427         owner->lastattrib  = attrib;
00428     }
00429     else
00430     {
00431         attrib = _xode_search(owner->firstattrib, name, XODE_TYPE_ATTRIB);
00432         if(attrib == NULL)
00433         {
00434             attrib = _xode_appendsibling(owner->lastattrib, name, XODE_TYPE_ATTRIB);
00435             owner->lastattrib = attrib;
00436         }
00437     }
00438     /* Update the value of the attribute */
00439     attrib->data_sz = strlen(value);
00440     attrib->data    = xode_pool_strdup(owner->p, value);
00441 
00442 }
00443 
00444 char* xode_get_attrib(xode owner, const char* name)
00445 {
00446     xode attrib;
00447 
00448     if (owner != NULL && owner->firstattrib != NULL)
00449     {
00450         attrib = _xode_search(owner->firstattrib, name, XODE_TYPE_ATTRIB);
00451         if (attrib != NULL)
00452             return (char*)attrib->data;
00453     }
00454     return NULL;
00455 }
00456 
00457 void xode_put_vattrib(xode owner, const char* name, void *value)
00458 {
00459     xode attrib;
00460 
00461     if (owner != NULL)
00462     {
00463         attrib = _xode_search(owner->firstattrib, name, XODE_TYPE_ATTRIB);
00464         if (attrib == NULL)
00465         {
00466             xode_put_attrib(owner, name, "");
00467             attrib = _xode_search(owner->firstattrib, name, XODE_TYPE_ATTRIB);
00468         }
00469         if (attrib != NULL)
00470             attrib->firstchild = (xode)value;
00471     }
00472 }
00473 
00474 void* xode_get_vattrib(xode owner, const char* name)
00475 {
00476     xode attrib;
00477 
00478     if (owner != NULL && owner->firstattrib != NULL)
00479     {
00480         attrib = _xode_search(owner->firstattrib, name, XODE_TYPE_ATTRIB);
00481         if (attrib != NULL)
00482             return (void*)attrib->firstchild;
00483     }
00484     return NULL;
00485 }
00486 
00487 xode xode_get_firstattrib(xode parent)
00488 {
00489     if (parent != NULL)
00490         return parent->firstattrib;
00491     return NULL;
00492 }
00493 
00494 xode xode_get_firstchild(xode parent)
00495 {
00496     if (parent != NULL)
00497         return parent->firstchild;
00498     return NULL;
00499 }
00500 
00501 xode xode_get_lastchild(xode parent)
00502 {
00503     if (parent != NULL)
00504         return parent->lastchild;
00505     return NULL;
00506 }
00507 
00508 xode xode_get_nextsibling(xode sibling)
00509 {
00510     if (sibling != NULL)
00511         return sibling->next;
00512     return NULL;
00513 }
00514 
00515 xode xode_get_prevsibling(xode sibling)
00516 {
00517     if (sibling != NULL)
00518         return sibling->prev;
00519     return NULL;
00520 }
00521 
00522 xode xode_get_parent(xode node)
00523 {
00524     if (node != NULL)
00525         return node->parent;
00526     return NULL;
00527 }
00528 
00529 char* xode_get_name(xode node)
00530 {
00531     if (node != NULL)
00532         return node->name;
00533     return NULL;
00534 }
00535 
00536 char* xode_get_data(xode node)
00537 {
00538     xode cur;
00539 
00540     if(node == NULL) return NULL;
00541 
00542     if(xode_get_type(node) == XODE_TYPE_TAG) /* loop till we find a CDATA */
00543     {
00544         for(cur = xode_get_firstchild(node); cur != NULL; cur = xode_get_nextsibling(cur))
00545             if(xode_get_type(cur) == XODE_TYPE_CDATA)
00546                 return cur->data;
00547     }else{
00548         return node->data;
00549     }
00550     return NULL;
00551 }
00552 
00553 int xode_get_datasz(xode node)
00554 {
00555         
00556     if( node == NULL )
00557     {
00558         return (int)NULL;           
00559     }       
00560     else if(xode_get_type(node) == XODE_TYPE_TAG) /* loop till we find a CDATA */
00561     {
00562         xode cur;       
00563         for(cur = xode_get_firstchild(node); cur != NULL; cur = xode_get_nextsibling(cur))
00564             if(xode_get_type(cur) == XODE_TYPE_CDATA)
00565                 return cur->data_sz;
00566     }else{
00567         return node->data_sz;
00568     }
00569     return (int)NULL;
00570 }
00571 
00572 int xode_get_type(xode node)
00573 {
00574     if (node != NULL)
00575     {
00576         return node->type;
00577     }
00578     return (int)NULL;
00579 }
00580 
00581 int xode_has_children(xode node)
00582 {
00583     if ((node != NULL) && (node->firstchild != NULL))
00584         return 1;
00585     return 0;
00586 }
00587 
00588 int xode_has_attribs(xode node)
00589 {
00590     if ((node != NULL) && (node->firstattrib != NULL))
00591         return 1;
00592     return 0;
00593 }
00594 
00595 xode_pool xode_get_pool(xode node)
00596 {
00597     if (node != NULL)
00598         return node->p;
00599     return (xode_pool)NULL;
00600 }
00601 
00602 void xode_hide(xode child)
00603 {
00604     xode parent;
00605 
00606     if(child == NULL || child->parent == NULL)
00607         return;
00608 
00609     parent = child->parent;
00610 
00611     /* first fix up at the child level */
00612     _xode_hidesibling(child);
00613 
00614     /* next fix up at the parent level */
00615     if(parent->firstchild == child)
00616         parent->firstchild = child->next;
00617     if(parent->lastchild == child)
00618         parent->lastchild = child->prev;
00619 }
00620 
00621 void xode_hide_attrib(xode parent, const char *name)
00622 {
00623     xode attrib;
00624 
00625     if(parent == NULL || parent->firstattrib == NULL || name == NULL)
00626         return;
00627 
00628     attrib = _xode_search(parent->firstattrib, name, XODE_TYPE_ATTRIB);
00629     if(attrib == NULL)
00630         return;
00631 
00632     /* first fix up at the child level */
00633     _xode_hidesibling(attrib);
00634 
00635     /* next fix up at the parent level */
00636     if(parent->firstattrib == attrib)
00637         parent->firstattrib = attrib->next;
00638     if(parent->lastattrib == attrib)
00639         parent->lastattrib = attrib->prev;
00640 }
00641 
00642 
00643 
00644 /*
00645  *  xode2str -- convert given xode tree into a string
00646  *
00647  *  parameters
00648  *      node -- pointer to the xode structure
00649  *
00650  *  results
00651  *      a pointer to the created string
00652  *      or NULL if it was unsuccessfull
00653  */
00654 char *xode_to_str(xode node)
00655 {
00656      return xode_spool_tostr(_xode_tospool(node));
00657 }
00658 
00659 
00660 /* loop through both a and b comparing everything, attribs, cdata, children, etc */
00661 int xode_cmp(xode a, xode b)
00662 {
00663     int ret = 0;
00664 
00665     while(1)
00666     {
00667         if(a == NULL && b == NULL)
00668             return 0;
00669 
00670         if(a == NULL || b == NULL)
00671             return -1;
00672 
00673         if(xode_get_type(a) != xode_get_type(b))
00674             return -1;
00675 
00676         switch(xode_get_type(a))
00677         {
00678         case XODE_TYPE_ATTRIB:
00679             ret = _xode_strcmp(xode_get_name(a), xode_get_name(b));
00680             if(ret != 0)
00681                 return -1;
00682             ret = _xode_strcmp(xode_get_data(a), xode_get_data(b));
00683             if(ret != 0)
00684                 return -1;
00685             break;
00686         case XODE_TYPE_TAG:
00687             ret = _xode_strcmp(xode_get_name(a), xode_get_name(b));
00688             if(ret != 0)
00689                 return -1;
00690             ret = xode_cmp(xode_get_firstattrib(a), xode_get_firstattrib(b));
00691             if(ret != 0)
00692                 return -1;
00693             ret = xode_cmp(xode_get_firstchild(a), xode_get_firstchild(b));
00694             if(ret != 0)
00695                 return -1;
00696             break;
00697         case XODE_TYPE_CDATA:
00698             ret = _xode_strcmp(xode_get_data(a), xode_get_data(b));
00699             if(ret != 0)
00700                 return -1;
00701         }
00702         a = xode_get_nextsibling(a);
00703         b = xode_get_nextsibling(b);
00704     }
00705 }
00706 
00707 
00708 xode xode_insert_tagnode(xode parent, xode node)
00709 {
00710     xode child;
00711 
00712     child = xode_insert_tag(parent, xode_get_name(node));
00713     if (xode_has_attribs(node))
00714         xode_insert_node(child, xode_get_firstattrib(node));
00715     if (xode_has_children(node))
00716         xode_insert_node(child, xode_get_firstchild(node));
00717 
00718     return child;
00719 }
00720 
00721 /* places copy of node and node's siblings in parent */
00722 void xode_insert_node(xode parent, xode node)
00723 {
00724     if(node == NULL || parent == NULL)
00725         return;
00726 
00727     while(node != NULL)
00728     {
00729         switch(xode_get_type(node))
00730         {
00731         case XODE_TYPE_ATTRIB:
00732             xode_put_attrib(parent, xode_get_name(node), xode_get_data(node));
00733             break;
00734         case XODE_TYPE_TAG:
00735             xode_insert_tagnode(parent, node);
00736             break;
00737         case XODE_TYPE_CDATA:
00738             xode_insert_cdata(parent, xode_get_data(node), xode_get_datasz(node));
00739         }
00740         node = xode_get_nextsibling(node);
00741     }
00742 }
00743 
00744 
00745 /* produce full duplicate of x with a new xode_pool, x must be a tag! */
00746 xode xode_dup(xode x)
00747 {
00748     xode x2;
00749 
00750     if(x == NULL)
00751         return NULL;
00752 
00753     x2 = xode_new(xode_get_name(x));
00754 
00755     if (xode_has_attribs(x))
00756         xode_insert_node(x2, xode_get_firstattrib(x));
00757     if (xode_has_children(x))
00758         xode_insert_node(x2, xode_get_firstchild(x));
00759 
00760     return x2;
00761 }
00762 
00763 xode xode_dup_frompool(xode_pool p, xode x)
00764 {
00765     xode x2;
00766 
00767     if(x == NULL)
00768         return NULL;
00769 
00770     x2 = xode_new_frompool(p, xode_get_name(x));
00771 
00772     if (xode_has_attribs(x))
00773         xode_insert_node(x2, xode_get_firstattrib(x));
00774     if (xode_has_children(x))
00775         xode_insert_node(x2, xode_get_firstchild(x));
00776 
00777     return x2;
00778 }
00779 
00780 xode xode_wrap(xode x,const char *wrapper)
00781 {
00782     xode wrap;
00783     if(x==NULL||wrapper==NULL) return NULL;
00784     wrap=xode_new_frompool(xode_get_pool(x),wrapper);
00785     if(wrap==NULL) return NULL;
00786     wrap->firstchild=x;
00787     wrap->lastchild=x;
00788     x->parent=wrap;
00789     return wrap;
00790 }
00791 
00792 void xode_free(xode node)
00793 {
00794     if(node == NULL)
00795         return;
00796 
00797     xode_pool_free(node->p);
00798 }
00799 
00800 
00801 void
00802 _xode_to_prettystr( xode_spool s, xode x, int deep )
00803 {
00804         int i;
00805         xode y;
00806 
00807         if(xode_get_type(x) != XODE_TYPE_TAG) return;
00808         
00809         for(i=0; i<deep; i++) xode_spool_add(s, "\t");  
00810 
00811         xode_spooler( s , "<" , xode_get_name(x) ,  s );
00812 
00813         y = xode_get_firstattrib(x);
00814         while( y )
00815         {
00816                 xode_spooler( s , " " , xode_get_name(y) , "='", xode_get_data(y) , "'" , s );
00817 
00818                 y = xode_get_nextsibling( y );
00819         }
00820         xode_spool_add(s,">");
00821         xode_spool_add(s,"\n");
00822                 
00823         if( xode_get_data(x))
00824         {
00825                 for(i=0; i<=deep; i++) xode_spool_add(s, "\t"); 
00826                 xode_spool_add( s , xode_get_data(x)); 
00827         }
00828                         
00829         y = xode_get_firstchild(x);
00830         while( y )
00831         {
00832                 _xode_to_prettystr(s , y, deep+1);
00833                 y = xode_get_nextsibling(y);
00834                 xode_spool_add(s,"\n");
00835         }
00836                 
00837         for(i=0; i<deep; i++) xode_spool_add(s, "\t");  
00838         xode_spooler( s , "</" , xode_get_name(x) , ">" , s );
00839 
00840         return;
00841 }
00842 
00843 char * 
00844 xode_to_prettystr( xode x )
00845 {
00846         xode_spool s;
00847 
00848         if( !x) return NULL;
00849         
00850         s = xode_spool_newfrompool( xode_get_pool(x));
00851 
00852         _xode_to_prettystr( s , x, 0 );
00853 
00854         return xode_spool_tostr(s);
00855 }
00856 


Last updated at Tue Dec 18 21:07:42 PST 2007. This site and project hosted by...SourceForge.net Logo
Source Perspective by Fisheye