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 #include "config.h"
00034 #include "mxml.h"
00035 #ifdef WIN32
00036 #  include <io.h>
00037 #else
00038 #  include <unistd.h>
00039 #endif 
00040 #include <fcntl.h>
00041 #ifndef O_BINARY
00042 #  define O_BINARY 0
00043 #endif 
00044 
00045 
00046 
00047 
00048 
00049 
00050 mxml_type_t     type_cb(mxml_node_t *node);
00051 const char      *whitespace_cb(mxml_node_t *node, int where);
00052 
00053 
00054 
00055 
00056 
00057 
00058 int                                     
00059 main(int  argc,                         
00060      char *argv[])                      
00061 {
00062   int                   i;              
00063   FILE                  *fp;            
00064   int                   fd;             
00065   mxml_node_t           *tree,          
00066                         *node;          
00067   mxml_index_t          *ind;           
00068   char                  buffer[16384];  
00069   static const char     *types[] =      
00070                         {
00071                           "MXML_ELEMENT",
00072                           "MXML_INTEGER",
00073                           "MXML_OPAQUE",
00074                           "MXML_REAL",
00075                           "MXML_TEXT"
00076                         };
00077 
00078 
00079  
00080 
00081 
00082 
00083   if (argc != 2)
00084   {
00085     fputs("Usage: testmxml filename.xml\n", stderr);
00086     return (1);
00087   }
00088 
00089  
00090 
00091 
00092 
00093   tree = mxmlNewElement(MXML_NO_PARENT, "element");
00094 
00095   if (!tree)
00096   {
00097     fputs("ERROR: No parent node in basic test!\n", stderr);
00098     return (1);
00099   }
00100 
00101   if (tree->type != MXML_ELEMENT)
00102   {
00103     fprintf(stderr, "ERROR: Parent has type %s (%d), expected MXML_ELEMENT!\n",
00104             tree->type < MXML_ELEMENT || tree->type > MXML_TEXT ?
00105                 "UNKNOWN" : types[tree->type], tree->type);
00106     mxmlDelete(tree);
00107     return (1);
00108   }
00109 
00110   if (strcmp(tree->value.element.name, "element"))
00111   {
00112     fprintf(stderr, "ERROR: Parent value is \"%s\", expected \"element\"!\n",
00113             tree->value.element.name);
00114     mxmlDelete(tree);
00115     return (1);
00116   }
00117 
00118   mxmlNewInteger(tree, 123);
00119   mxmlNewOpaque(tree, "opaque");
00120   mxmlNewReal(tree, 123.4f);
00121   mxmlNewText(tree, 1, "text");
00122 
00123   mxmlLoadString(tree, "<group type='string'>string string string</group>",
00124                  MXML_NO_CALLBACK);
00125   mxmlLoadString(tree, "<group type='integer'>1 2 3</group>",
00126                  MXML_INTEGER_CALLBACK);
00127   mxmlLoadString(tree, "<group type='real'>1.0 2.0 3.0</group>",
00128                  MXML_REAL_CALLBACK);
00129   mxmlLoadString(tree, "<group>opaque opaque opaque</group>",
00130                  MXML_OPAQUE_CALLBACK);
00131 
00132   node = tree->child;
00133 
00134   if (!node)
00135   {
00136     fputs("ERROR: No first child node in basic test!\n", stderr);
00137     mxmlDelete(tree);
00138     return (1);
00139   }
00140 
00141   if (node->type != MXML_INTEGER)
00142   {
00143     fprintf(stderr, "ERROR: First child has type %s (%d), expected MXML_INTEGER!\n",
00144             node->type < MXML_ELEMENT || node->type > MXML_TEXT ?
00145                 "UNKNOWN" : types[node->type], node->type);
00146     mxmlDelete(tree);
00147     return (1);
00148   }
00149 
00150   if (node->value.integer != 123)
00151   {
00152     fprintf(stderr, "ERROR: First child value is %d, expected 123!\n",
00153             node->value.integer);
00154     mxmlDelete(tree);
00155     return (1);
00156   }
00157 
00158   node = node->next;
00159 
00160   if (!node)
00161   {
00162     fputs("ERROR: No second child node in basic test!\n", stderr);
00163     mxmlDelete(tree);
00164     return (1);
00165   }
00166 
00167   if (node->type != MXML_OPAQUE)
00168   {
00169     fprintf(stderr, "ERROR: Second child has type %s (%d), expected MXML_OPAQUE!\n",
00170             node->type < MXML_ELEMENT || node->type > MXML_TEXT ?
00171                 "UNKNOWN" : types[node->type], node->type);
00172     mxmlDelete(tree);
00173     return (1);
00174   }
00175 
00176   if (!node->value.opaque || strcmp(node->value.opaque, "opaque"))
00177   {
00178     fprintf(stderr, "ERROR: Second child value is \"%s\", expected \"opaque\"!\n",
00179             node->value.opaque ? node->value.opaque : "(null)");
00180     mxmlDelete(tree);
00181     return (1);
00182   }
00183 
00184   node = node->next;
00185 
00186   if (!node)
00187   {
00188     fputs("ERROR: No third child node in basic test!\n", stderr);
00189     mxmlDelete(tree);
00190     return (1);
00191   }
00192 
00193   if (node->type != MXML_REAL)
00194   {
00195     fprintf(stderr, "ERROR: Third child has type %s (%d), expected MXML_REAL!\n",
00196             node->type < MXML_ELEMENT || node->type > MXML_TEXT ?
00197                 "UNKNOWN" : types[node->type], node->type);
00198     mxmlDelete(tree);
00199     return (1);
00200   }
00201 
00202   if (node->value.real != 123.4f)
00203   {
00204     fprintf(stderr, "ERROR: Third child value is %f, expected 123.4!\n",
00205             node->value.real);
00206     mxmlDelete(tree);
00207     return (1);
00208   }
00209 
00210   node = node->next;
00211 
00212   if (!node)
00213   {
00214     fputs("ERROR: No fourth child node in basic test!\n", stderr);
00215     mxmlDelete(tree);
00216     return (1);
00217   }
00218 
00219   if (node->type != MXML_TEXT)
00220   {
00221     fprintf(stderr, "ERROR: Fourth child has type %s (%d), expected MXML_TEXT!\n",
00222             node->type < MXML_ELEMENT || node->type > MXML_TEXT ?
00223                 "UNKNOWN" : types[node->type], node->type);
00224     mxmlDelete(tree);
00225     return (1);
00226   }
00227 
00228   if (!node->value.text.whitespace ||
00229       !node->value.text.string || strcmp(node->value.text.string, "text"))
00230   {
00231     fprintf(stderr, "ERROR: Fourth child value is %d,\"%s\", expected 1,\"text\"!\n",
00232             node->value.text.whitespace,
00233             node->value.text.string ? node->value.text.string : "(null)");
00234     mxmlDelete(tree);
00235     return (1);
00236   }
00237 
00238   for (i = 0; i < 4; i ++)
00239   {
00240     node = node->next;
00241 
00242     if (!node)
00243     {
00244       fprintf(stderr, "ERROR: No group #%d child node in basic test!\n", i + 1);
00245       mxmlDelete(tree);
00246       return (1);
00247     }
00248 
00249     if (node->type != MXML_ELEMENT)
00250     {
00251       fprintf(stderr, "ERROR: Group child #%d has type %s (%d), expected MXML_ELEMENT!\n",
00252               i + 1, node->type < MXML_ELEMENT || node->type > MXML_TEXT ?
00253                          "UNKNOWN" : types[node->type], node->type);
00254       mxmlDelete(tree);
00255       return (1);
00256     }
00257   }
00258 
00259  
00260 
00261 
00262 
00263   ind = mxmlIndexNew(tree, NULL, NULL);
00264   if (!ind)
00265   {
00266     fputs("ERROR: Unable to create index of all nodes!\n", stderr);
00267     mxmlDelete(tree);
00268     return (1);
00269   }
00270 
00271   if (ind->num_nodes != 5)
00272   {
00273     fprintf(stderr, "ERROR: Index of all nodes contains %d "
00274                     "nodes; expected 5!\n", ind->num_nodes);
00275     mxmlIndexDelete(ind);
00276     mxmlDelete(tree);
00277     return (1);
00278   }
00279 
00280   mxmlIndexReset(ind);
00281   if (!mxmlIndexFind(ind, "group", NULL))
00282   {
00283     fputs("ERROR: mxmlIndexFind for \"group\" failed!\n", stderr);
00284     mxmlIndexDelete(ind);
00285     mxmlDelete(tree);
00286     return (1);
00287   }
00288 
00289   mxmlIndexDelete(ind);
00290 
00291   ind = mxmlIndexNew(tree, "group", NULL);
00292   if (!ind)
00293   {
00294     fputs("ERROR: Unable to create index of groups!\n", stderr);
00295     mxmlDelete(tree);
00296     return (1);
00297   }
00298 
00299   if (ind->num_nodes != 4)
00300   {
00301     fprintf(stderr, "ERROR: Index of groups contains %d "
00302                     "nodes; expected 4!\n", ind->num_nodes);
00303     mxmlIndexDelete(ind);
00304     mxmlDelete(tree);
00305     return (1);
00306   }
00307 
00308   mxmlIndexReset(ind);
00309   if (!mxmlIndexEnum(ind))
00310   {
00311     fputs("ERROR: mxmlIndexEnum failed!\n", stderr);
00312     mxmlIndexDelete(ind);
00313     mxmlDelete(tree);
00314     return (1);
00315   }
00316 
00317   mxmlIndexDelete(ind);
00318 
00319   ind = mxmlIndexNew(tree, NULL, "type");
00320   if (!ind)
00321   {
00322     fputs("ERROR: Unable to create index of type attributes!\n", stderr);
00323     mxmlDelete(tree);
00324     return (1);
00325   }
00326 
00327   if (ind->num_nodes != 3)
00328   {
00329     fprintf(stderr, "ERROR: Index of type attributes contains %d "
00330                     "nodes; expected 3!\n", ind->num_nodes);
00331     mxmlIndexDelete(ind);
00332     mxmlDelete(tree);
00333     return (1);
00334   }
00335 
00336   mxmlIndexReset(ind);
00337   if (!mxmlIndexFind(ind, NULL, "string"))
00338   {
00339     fputs("ERROR: mxmlIndexFind for \"string\" failed!\n", stderr);
00340     mxmlIndexDelete(ind);
00341     mxmlDelete(tree);
00342     return (1);
00343   }
00344 
00345   mxmlIndexDelete(ind);
00346 
00347   ind = mxmlIndexNew(tree, "group", "type");
00348   if (!ind)
00349   {
00350     fputs("ERROR: Unable to create index of elements and attributes!\n", stderr);
00351     mxmlDelete(tree);
00352     return (1);
00353   }
00354 
00355   if (ind->num_nodes != 3)
00356   {
00357     fprintf(stderr, "ERROR: Index of elements and attributes contains %d "
00358                     "nodes; expected 3!\n", ind->num_nodes);
00359     mxmlIndexDelete(ind);
00360     mxmlDelete(tree);
00361     return (1);
00362   }
00363 
00364   mxmlIndexReset(ind);
00365   if (!mxmlIndexFind(ind, "group", "string"))
00366   {
00367     fputs("ERROR: mxmlIndexFind for \"string\" failed!\n", stderr);
00368     mxmlIndexDelete(ind);
00369     mxmlDelete(tree);
00370     return (1);
00371   }
00372 
00373   mxmlIndexDelete(ind);
00374 
00375  
00376 
00377 
00378 
00379   for (i = 0; i < 8; i ++)
00380   {
00381     if (tree->child)
00382       mxmlDelete(tree->child);
00383     else
00384     {
00385       fprintf(stderr, "ERROR: Child pointer prematurely NULL on child #%d\n",
00386               i + 1);
00387       mxmlDelete(tree);
00388       return (1);
00389     }
00390   }
00391 
00392   if (tree->child)
00393   {
00394     fputs("ERROR: Child pointer not NULL after deleting all children!\n", stderr);
00395     return (1);
00396   }
00397 
00398   if (tree->last_child)
00399   {
00400     fputs("ERROR: Last child pointer not NULL after deleting all children!\n", stderr);
00401     return (1);
00402   }
00403 
00404   mxmlDelete(tree);
00405 
00406  
00407 
00408 
00409 
00410   if (argv[1][0] == '<')
00411     tree = mxmlLoadString(NULL, argv[1], type_cb);
00412   else if ((fp = fopen(argv[1], "rb")) == NULL)
00413   {
00414     perror(argv[1]);
00415     return (1);
00416   }
00417   else
00418   {
00419    
00420 
00421 
00422 
00423     tree = mxmlLoadFile(NULL, fp, type_cb);
00424 
00425     fclose(fp);
00426   }
00427 
00428   if (!tree)
00429   {
00430     fputs("Unable to read XML file!\n", stderr);
00431     return (1);
00432   }
00433 
00434   if (!strcmp(argv[1], "test.xml"))
00435   {
00436    
00437 
00438 
00439 
00440 
00441     if ((node = mxmlFindElement(tree, tree, "choice", NULL, NULL,
00442                                 MXML_DESCEND)) == NULL)
00443     {
00444       fputs("Unable to find first <choice> element in XML tree!\n", stderr);
00445       mxmlDelete(tree);
00446       return (1);
00447     }
00448 
00449     if ((node = mxmlFindElement(node, tree, "choice", NULL, NULL,
00450                                 MXML_NO_DESCEND)) == NULL)
00451     {
00452       fputs("Unable to find second <choice> element in XML tree!\n", stderr);
00453       mxmlDelete(tree);
00454       return (1);
00455     }
00456   }
00457 
00458  
00459 
00460 
00461 
00462   mxmlSaveFile(tree, stdout, whitespace_cb);
00463 
00464  
00465 
00466 
00467 
00468   if (mxmlSaveString(tree, buffer, sizeof(buffer), whitespace_cb) > 0)
00469     fputs(buffer, stderr);
00470 
00471  
00472 
00473 
00474 
00475   mxmlDelete(tree);
00476 
00477  
00478 
00479 
00480 
00481   if (argv[1][0] != '<')
00482   {
00483    
00484 
00485 
00486 
00487     if ((fd = open(argv[1], O_RDONLY | O_BINARY)) < 0)
00488     {
00489       perror(argv[1]);
00490       return (1);
00491     }
00492 
00493    
00494 
00495 
00496 
00497     tree = mxmlLoadFd(NULL, fd, type_cb);
00498 
00499     close(fd);
00500 
00501    
00502 
00503 
00504 
00505     snprintf(buffer, sizeof(buffer), "%sfd", argv[1]);
00506 
00507     if ((fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)) < 0)
00508     {
00509       perror(buffer);
00510       mxmlDelete(tree);
00511       return (1);
00512     }
00513 
00514    
00515 
00516 
00517 
00518     mxmlSaveFd(tree, fd, whitespace_cb);
00519 
00520     close(fd);
00521 
00522    
00523 
00524 
00525 
00526     mxmlDelete(tree);
00527   }
00528 
00529  
00530 
00531 
00532 
00533   return (0);
00534 }
00535 
00536 
00537 
00538 
00539 
00540 
00541 mxml_type_t                             
00542 type_cb(mxml_node_t *node)              
00543 {
00544   const char    *type;                  
00545 
00546 
00547  
00548 
00549 
00550 
00551   if ((type = mxmlElementGetAttr(node, "type")) == NULL)
00552     type = node->value.element.name;
00553 
00554   if (!strcmp(type, "integer"))
00555     return (MXML_INTEGER);
00556   else if (!strcmp(type, "opaque") || !strcmp(type, "pre"))
00557     return (MXML_OPAQUE);
00558   else if (!strcmp(type, "real"))
00559     return (MXML_REAL);
00560   else
00561     return (MXML_TEXT);
00562 }
00563 
00564 
00565 
00566 
00567 
00568 
00569 
00570 const char *                            
00571 whitespace_cb(mxml_node_t *node,        
00572               int         where)        
00573 {
00574   mxml_node_t   *parent;                
00575   int           level;                  
00576   const char    *name;                  
00577   static const char *tabs = "\t\t\t\t\t\t\t\t";
00578                                         
00579 
00580 
00581  
00582 
00583 
00584 
00585 
00586   name = node->value.element.name;
00587 
00588   if (!strcmp(name, "html") || !strcmp(name, "head") || !strcmp(name, "body") ||
00589       !strcmp(name, "pre") || !strcmp(name, "p") ||
00590       !strcmp(name, "h1") || !strcmp(name, "h2") || !strcmp(name, "h3") ||
00591       !strcmp(name, "h4") || !strcmp(name, "h5") || !strcmp(name, "h6"))
00592   {
00593    
00594 
00595 
00596 
00597     if (where == MXML_WS_BEFORE_OPEN || where == MXML_WS_AFTER_CLOSE)
00598       return ("\n");
00599   }
00600   else if (!strcmp(name, "dl") || !strcmp(name, "ol") || !strcmp(name, "ul"))
00601   {
00602    
00603 
00604 
00605 
00606     return ("\n");
00607   }
00608   else if (!strcmp(name, "dd") || !strcmp(name, "dt") || !strcmp(name, "li"))
00609   {
00610    
00611 
00612 
00613 
00614     if (where == MXML_WS_BEFORE_OPEN)
00615       return ("\t");
00616     else if (where == MXML_WS_AFTER_CLOSE)
00617       return ("\n");
00618   }
00619   else if (!strcmp(name, "?xml"))
00620   {
00621     return (NULL);
00622   }
00623   else if (where == MXML_WS_BEFORE_OPEN ||
00624            ((!strcmp(name, "choice") || !strcmp(name, "option")) &&
00625             where == MXML_WS_BEFORE_CLOSE))
00626   {
00627     for (level = -1, parent = node->parent;
00628          parent;
00629          level ++, parent = parent->parent);
00630 
00631     if (level > 8)
00632       level = 8;
00633     else if (level < 0)
00634       level = 0;
00635 
00636     return (tabs + 8 - level);
00637   }
00638   else if (where == MXML_WS_AFTER_CLOSE ||
00639            ((!strcmp(name, "group") || !strcmp(name, "option") ||
00640              !strcmp(name, "choice")) &&
00641             where == MXML_WS_AFTER_OPEN))
00642     return ("\n");
00643   else if (where == MXML_WS_AFTER_OPEN && !node->child)
00644     return ("\n");
00645 
00646  
00647 
00648 
00649 
00650   return (NULL);
00651 }
00652 
00653 
00654 
00655 
00656