00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 #include "config.h"
00040 #include "mxml.h"
00041 
00042 
00043 
00044 
00045 
00046 
00047 static mxml_node_t      *mxml_new(mxml_node_t *parent, mxml_type_t type);
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 void
00062 mxmlAdd(mxml_node_t *parent,            
00063         int         where,              
00064         mxml_node_t *child,             
00065         mxml_node_t *node)              
00066 {
00067 #ifdef DEBUG
00068   fprintf(stderr, "mxmlAdd(parent=%p, where=%d, child=%p, node=%p)\n", parent,
00069           where, child, node);
00070 #endif 
00071 
00072  
00073 
00074 
00075 
00076   if (!parent || !node)
00077     return;
00078 
00079 #if DEBUG > 1
00080   fprintf(stderr, "    BEFORE: node->parent=%p\n", node->parent);
00081   if (parent)
00082   {
00083     fprintf(stderr, "    BEFORE: parent->child=%p\n", parent->child);
00084     fprintf(stderr, "    BEFORE: parent->last_child=%p\n", parent->last_child);
00085     fprintf(stderr, "    BEFORE: parent->prev=%p\n", parent->prev);
00086     fprintf(stderr, "    BEFORE: parent->next=%p\n", parent->next);
00087   }
00088 #endif 
00089 
00090  
00091 
00092 
00093 
00094   if (node->parent)
00095     mxmlRemove(node);
00096 
00097  
00098 
00099 
00100 
00101   node->parent = parent;
00102 
00103   switch (where)
00104   {
00105     case MXML_ADD_BEFORE :
00106         if (!child || child == parent->child || child->parent != parent)
00107         {
00108          
00109 
00110 
00111 
00112           node->next = parent->child;
00113 
00114           if (parent->child)
00115             parent->child->prev = node;
00116           else
00117             parent->last_child = node;
00118 
00119           parent->child = node;
00120         }
00121         else
00122         {
00123          
00124 
00125 
00126 
00127           node->next = child;
00128           node->prev = child->prev;
00129 
00130           if (child->prev)
00131             child->prev->next = node;
00132           else
00133             parent->child = node;
00134 
00135           child->prev = node;
00136         }
00137         break;
00138 
00139     case MXML_ADD_AFTER :
00140         if (!child || child == parent->last_child || child->parent != parent)
00141         {
00142          
00143 
00144 
00145 
00146           node->parent = parent;
00147           node->prev   = parent->last_child;
00148 
00149           if (parent->last_child)
00150             parent->last_child->next = node;
00151           else
00152             parent->child = node;
00153 
00154           parent->last_child = node;
00155         }
00156         else
00157         {
00158          
00159 
00160 
00161 
00162           node->prev = child;
00163           node->next = child->next;
00164 
00165           if (child->next)
00166             child->next->prev = node;
00167           else
00168             parent->last_child = node;
00169 
00170           child->next = node;
00171         }
00172         break;
00173   }
00174 
00175 #if DEBUG > 1
00176   fprintf(stderr, "    AFTER: node->parent=%p\n", node->parent);
00177   if (parent)
00178   {
00179     fprintf(stderr, "    AFTER: parent->child=%p\n", parent->child);
00180     fprintf(stderr, "    AFTER: parent->last_child=%p\n", parent->last_child);
00181     fprintf(stderr, "    AFTER: parent->prev=%p\n", parent->prev);
00182     fprintf(stderr, "    AFTER: parent->next=%p\n", parent->next);
00183   }
00184 #endif 
00185 }
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 void
00196 mxmlDelete(mxml_node_t *node)           
00197 {
00198   int   i;                              
00199 
00200 
00201 #ifdef DEBUG
00202   fprintf(stderr, "mxmlDelete(node=%p)\n", node);
00203 #endif 
00204 
00205  
00206 
00207 
00208 
00209   if (!node)
00210     return;
00211 
00212  
00213 
00214 
00215 
00216   mxmlRemove(node);
00217 
00218  
00219 
00220 
00221 
00222   while (node->child)
00223     mxmlDelete(node->child);
00224 
00225  
00226 
00227 
00228 
00229   switch (node->type)
00230   {
00231     case MXML_ELEMENT :
00232         if (node->value.element.name)
00233           free(node->value.element.name);
00234 
00235         if (node->value.element.num_attrs)
00236         {
00237           for (i = 0; i < node->value.element.num_attrs; i ++)
00238           {
00239             if (node->value.element.attrs[i].name)
00240               free(node->value.element.attrs[i].name);
00241             if (node->value.element.attrs[i].value)
00242               free(node->value.element.attrs[i].value);
00243           }
00244 
00245           free(node->value.element.attrs);
00246         }
00247         break;
00248     case MXML_INTEGER :
00249        
00250         break;
00251     case MXML_OPAQUE :
00252         if (node->value.opaque)
00253           free(node->value.opaque);
00254         break;
00255     case MXML_REAL :
00256        
00257         break;
00258     case MXML_TEXT :
00259         if (node->value.text.string)
00260           free(node->value.text.string);
00261         break;
00262     case MXML_CUSTOM :
00263         if (node->value.custom.data &&
00264             node->value.custom.destroy)
00265           (*(node->value.custom.destroy))(node->value.custom.data);
00266         break;
00267   }
00268 
00269  
00270 
00271 
00272 
00273   free(node);
00274 }
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286 mxml_node_t *                           
00287 mxmlNewCustom(mxml_node_t *parent,      
00288               void        *data,        
00289               void        (*destroy)(void *))
00290                                         
00291 {
00292   mxml_node_t   *node;                  
00293 
00294 
00295 #ifdef DEBUG
00296   fprintf(stderr, "mxmlNewCustom(parent=%p, data=%p, destroy=%p)\n", parent,
00297           data, destroy);
00298 #endif 
00299 
00300  
00301 
00302 
00303 
00304   if ((node = mxml_new(parent, MXML_CUSTOM)) != NULL)
00305   {
00306     node->value.custom.data    = data;
00307     node->value.custom.destroy = destroy;
00308   }
00309 
00310   return (node);
00311 }
00312 
00313 
00314 
00315 
00316 
00317 
00318 
00319 
00320 
00321 
00322 mxml_node_t *                           
00323 mxmlNewElement(mxml_node_t *parent,     
00324                const char  *name)       
00325 {
00326   mxml_node_t   *node;                  
00327 
00328 
00329 #ifdef DEBUG
00330   fprintf(stderr, "mxmlNewElement(parent=%p, name=\"%s\")\n", parent,
00331           name ? name : "(null)");
00332 #endif 
00333 
00334  
00335 
00336 
00337 
00338   if (!name)
00339     return (NULL);
00340 
00341  
00342 
00343 
00344 
00345   if ((node = mxml_new(parent, MXML_ELEMENT)) != NULL)
00346     node->value.element.name = strdup(name);
00347 
00348   return (node);
00349 }
00350 
00351 
00352 
00353 
00354 
00355 
00356 
00357 
00358 
00359 
00360 mxml_node_t *                           
00361 mxmlNewInteger(mxml_node_t *parent,     
00362                int         integer)     
00363 {
00364   mxml_node_t   *node;                  
00365 
00366 
00367 #ifdef DEBUG
00368   fprintf(stderr, "mxmlNewInteger(parent=%p, integer=%d)\n", parent, integer);
00369 #endif 
00370 
00371  
00372 
00373 
00374 
00375   if ((node = mxml_new(parent, MXML_INTEGER)) != NULL)
00376     node->value.integer = integer;
00377 
00378   return (node);
00379 }
00380 
00381 
00382 
00383 
00384 
00385 
00386 
00387 
00388 
00389 
00390 
00391 mxml_node_t *                           
00392 mxmlNewOpaque(mxml_node_t *parent,      
00393               const char  *opaque)      
00394 {
00395   mxml_node_t   *node;                  
00396 
00397 
00398 #ifdef DEBUG
00399   fprintf(stderr, "mxmlNewOpaque(parent=%p, opaque=\"%s\")\n", parent,
00400           opaque ? opaque : "(null)");
00401 #endif 
00402 
00403  
00404 
00405 
00406 
00407   if (!opaque)
00408     return (NULL);
00409 
00410  
00411 
00412 
00413 
00414   if ((node = mxml_new(parent, MXML_OPAQUE)) != NULL)
00415     node->value.opaque = strdup(opaque);
00416 
00417   return (node);
00418 }
00419 
00420 
00421 
00422 
00423 
00424 
00425 
00426 
00427 
00428 
00429 mxml_node_t *                           
00430 mxmlNewReal(mxml_node_t *parent,        
00431             double      real)           
00432 {
00433   mxml_node_t   *node;                  
00434 
00435 
00436 #ifdef DEBUG
00437   fprintf(stderr, "mxmlNewReal(parent=%p, real=%g)\n", parent, real);
00438 #endif 
00439 
00440  
00441 
00442 
00443 
00444   if ((node = mxml_new(parent, MXML_REAL)) != NULL)
00445     node->value.real = real;
00446 
00447   return (node);
00448 }
00449 
00450 
00451 
00452 
00453 
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 mxml_node_t *                           
00462 mxmlNewText(mxml_node_t *parent,        
00463             int         whitespace,     
00464             const char  *string)        
00465 {
00466   mxml_node_t   *node;                  
00467 
00468 
00469 #ifdef DEBUG
00470   fprintf(stderr, "mxmlNewText(parent=%p, whitespace=%d, string=\"%s\")\n",
00471           parent, whitespace, string ? string : "(null)");
00472 #endif 
00473 
00474  
00475 
00476 
00477 
00478   if (!string)
00479     return (NULL);
00480 
00481  
00482 
00483 
00484 
00485   if ((node = mxml_new(parent, MXML_TEXT)) != NULL)
00486   {
00487     node->value.text.whitespace = whitespace;
00488     node->value.text.string     = strdup(string);
00489   }
00490 
00491   return (node);
00492 }
00493 
00494 
00495 
00496 
00497 
00498 
00499 
00500 
00501 
00502 
00503 
00504 
00505 mxml_node_t *                           
00506 mxmlNewTextf(mxml_node_t *parent,       
00507              int         whitespace,    
00508              const char  *format,       
00509              ...)                       
00510 {
00511   mxml_node_t   *node;                  
00512   va_list       ap;                     
00513 
00514 
00515 #ifdef DEBUG
00516   fprintf(stderr, "mxmlNewTextf(parent=%p, whitespace=%d, format=\"%s\", ...)\n",
00517           parent, whitespace, format ? format : "(null)");
00518 #endif 
00519 
00520  
00521 
00522 
00523 
00524   if (!format)
00525     return (NULL);
00526 
00527  
00528 
00529 
00530 
00531   if ((node = mxml_new(parent, MXML_TEXT)) != NULL)
00532   {
00533     va_start(ap, format);
00534 
00535     node->value.text.whitespace = whitespace;
00536     node->value.text.string     = mxml_strdupf(format, ap);
00537 
00538     va_end(ap);
00539   }
00540 
00541   return (node);
00542 }
00543 
00544 
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 void
00553 mxmlRemove(mxml_node_t *node)           
00554 {
00555 #ifdef DEBUG
00556   fprintf(stderr, "mxmlRemove(node=%p)\n", node);
00557 #endif 
00558 
00559  
00560 
00561 
00562 
00563   if (!node || !node->parent)
00564     return;
00565 
00566  
00567 
00568 
00569 
00570 #if DEBUG > 1
00571   fprintf(stderr, "    BEFORE: node->parent=%p\n", node->parent);
00572   if (node->parent)
00573   {
00574     fprintf(stderr, "    BEFORE: node->parent->child=%p\n", node->parent->child);
00575     fprintf(stderr, "    BEFORE: node->parent->last_child=%p\n", node->parent->last_child);
00576   }
00577   fprintf(stderr, "    BEFORE: node->child=%p\n", node->child);
00578   fprintf(stderr, "    BEFORE: node->last_child=%p\n", node->last_child);
00579   fprintf(stderr, "    BEFORE: node->prev=%p\n", node->prev);
00580   fprintf(stderr, "    BEFORE: node->next=%p\n", node->next);
00581 #endif 
00582 
00583   if (node->prev)
00584     node->prev->next = node->next;
00585   else
00586     node->parent->child = node->next;
00587 
00588   if (node->next)
00589     node->next->prev = node->prev;
00590   else
00591     node->parent->last_child = node->prev;
00592 
00593   node->parent = NULL;
00594   node->prev   = NULL;
00595   node->next   = NULL;
00596 
00597 #if DEBUG > 1
00598   fprintf(stderr, "    AFTER: node->parent=%p\n", node->parent);
00599   if (node->parent)
00600   {
00601     fprintf(stderr, "    AFTER: node->parent->child=%p\n", node->parent->child);
00602     fprintf(stderr, "    AFTER: node->parent->last_child=%p\n", node->parent->last_child);
00603   }
00604   fprintf(stderr, "    AFTER: node->child=%p\n", node->child);
00605   fprintf(stderr, "    AFTER: node->last_child=%p\n", node->last_child);
00606   fprintf(stderr, "    AFTER: node->prev=%p\n", node->prev);
00607   fprintf(stderr, "    AFTER: node->next=%p\n", node->next);
00608 #endif 
00609 }
00610 
00611 
00612 
00613 
00614 
00615 
00616 static mxml_node_t *                    
00617 mxml_new(mxml_node_t *parent,           
00618          mxml_type_t type)              
00619 {
00620   mxml_node_t   *node;                  
00621 
00622 
00623 #if DEBUG > 1
00624   fprintf(stderr, "mxml_new(parent=%p, type=%d)\n", parent, type);
00625 #endif 
00626 
00627  
00628 
00629 
00630 
00631   if ((node = calloc(1, sizeof(mxml_node_t))) == NULL)
00632   {
00633 #if DEBUG > 1
00634     fputs("    returning NULL\n", stderr);
00635 #endif 
00636 
00637     return (NULL);
00638   }
00639 
00640 #if DEBUG > 1
00641   fprintf(stderr, "    returning %p\n", node);
00642 #endif 
00643 
00644  
00645 
00646 
00647 
00648   node->type = type;
00649 
00650  
00651 
00652 
00653 
00654   if (parent)
00655     mxmlAdd(parent, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, node);
00656 
00657  
00658 
00659 
00660 
00661   return (node);
00662 }
00663 
00664 
00665 
00666 
00667