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 #include "config.h"
00039 #include "mxml.h"
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 #define STATE_NONE 0
00121 #define STATE_PREPROCESSOR 1
00122 #define STATE_C_COMMENT 2
00123 #define STATE_CXX_COMMENT 3
00124 #define STATE_STRING 4
00125 #define STATE_CHARACTER 5
00126 #define STATE_IDENTIFIER 6
00127
00128
00129
00130
00131
00132
00133 static mxml_node_t *add_variable(mxml_node_t *parent, const char *name,
00134 mxml_node_t *type);
00135 static void safe_strcpy(char *dst, const char *src);
00136 static int scan_file(const char *filename, FILE *fp,
00137 mxml_node_t *doc);
00138 static void sort_node(mxml_node_t *tree, mxml_node_t *func);
00139 static void update_comment(mxml_node_t *parent,
00140 mxml_node_t *comment);
00141 static void write_documentation(mxml_node_t *doc);
00142 static void write_element(mxml_node_t *doc, mxml_node_t *element);
00143 static void write_string(const char *s);
00144 static const char *ws_cb(mxml_node_t *node, int where);
00145
00146
00147
00148
00149
00150
00151 int
00152 main(int argc,
00153 char *argv[])
00154 {
00155 int i;
00156 FILE *fp;
00157 mxml_node_t *doc;
00158 mxml_node_t *mxmldoc;
00159
00160
00161
00162
00163
00164
00165 if (argc < 2)
00166 {
00167 fputs("Usage: mxmldoc filename.xml [source files] >filename.html\n", stderr);
00168 return (1);
00169 }
00170
00171
00172
00173
00174
00175 if ((fp = fopen(argv[1], "r")) != NULL)
00176 {
00177
00178
00179
00180
00181 doc = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
00182
00183 fclose(fp);
00184
00185 if (!doc)
00186 {
00187 mxmldoc = NULL;
00188
00189 fprintf(stderr, "mxmldoc: Unable to read the XML documentation file \"%s\"!\n",
00190 argv[1]);
00191 }
00192 else if ((mxmldoc = mxmlFindElement(doc, doc, "mxmldoc", NULL,
00193 NULL, MXML_DESCEND)) == NULL)
00194 {
00195 fprintf(stderr, "mxmldoc: XML documentation file \"%s\" is missing <mxmldoc> node!!\n",
00196 argv[1]);
00197
00198 mxmlDelete(doc);
00199 doc = NULL;
00200 }
00201 }
00202 else
00203 {
00204 doc = NULL;
00205 mxmldoc = NULL;
00206 }
00207
00208 if (!doc)
00209 {
00210
00211
00212
00213
00214 doc = mxmlNewElement(NULL, "?xml version=\"1.0\"?");
00215
00216 mxmldoc = mxmlNewElement(doc, "mxmldoc");
00217
00218 #ifdef MXML_INCLUDE_SCHEMA
00219
00220
00221
00222
00223
00224 mxmlElementSetAttr(mxmldoc, "xmlns", "http://www.easysw.com");
00225 mxmlElementSetAttr(mxmldoc, "xmlns:xsi",
00226 "http://www.w3.org/2001/XMLSchema-instance");
00227 mxmlElementSetAttr(mxmldoc, "xsi:schemaLocation",
00228 "http://www.easysw.com/~mike/mxml/mxmldoc.xsd");
00229 #endif
00230 }
00231
00232
00233
00234
00235
00236 for (i = 2; i < argc; i ++)
00237 if ((fp = fopen(argv[i], "r")) == NULL)
00238 {
00239 fprintf(stderr, "Unable to open source file \"%s\": %s\n", argv[i],
00240 strerror(errno));
00241 mxmlDelete(doc);
00242 return (1);
00243 }
00244 else if (scan_file(argv[i], fp, mxmldoc))
00245 {
00246 fclose(fp);
00247 mxmlDelete(doc);
00248 return (1);
00249 }
00250 else
00251 fclose(fp);
00252
00253 if (argc > 2)
00254 {
00255
00256
00257
00258
00259 if ((fp = fopen(argv[1], "w")) != NULL)
00260 {
00261
00262
00263
00264
00265 if (mxmlSaveFile(doc, fp, ws_cb))
00266 {
00267 fprintf(stderr, "Unable to write the XML documentation file \"%s\": %s!\n",
00268 argv[1], strerror(errno));
00269 fclose(fp);
00270 mxmlDelete(doc);
00271 return (1);
00272 }
00273
00274 fclose(fp);
00275 }
00276 else
00277 {
00278 fprintf(stderr, "Unable to create the XML documentation file \"%s\": %s!\n",
00279 argv[1], strerror(errno));
00280 mxmlDelete(doc);
00281 return (1);
00282 }
00283 }
00284
00285
00286
00287
00288
00289 write_documentation(mxmldoc);
00290
00291
00292
00293
00294
00295 mxmlDelete(doc);
00296
00297 return (0);
00298 }
00299
00300
00301
00302
00303
00304
00305 static mxml_node_t *
00306 add_variable(mxml_node_t *parent,
00307 const char *name,
00308 mxml_node_t *type)
00309 {
00310 mxml_node_t *variable,
00311 *node,
00312 *next;
00313 char buffer[16384],
00314 *bufptr;
00315
00316
00317
00318
00319
00320
00321 if (!type || !type->child)
00322 return (NULL);
00323
00324
00325
00326
00327
00328 variable = mxmlNewElement(parent, name);
00329
00330
00331
00332
00333
00334 for (node = type->child; node; node = node->next)
00335 if (!strcmp(node->value.text.string, "="))
00336 break;
00337
00338 if (node)
00339 {
00340
00341
00342
00343
00344 for (bufptr = buffer; node; bufptr += strlen(bufptr))
00345 {
00346 if (node->value.text.whitespace && bufptr > buffer)
00347 *bufptr++ = ' ';
00348
00349 strcpy(bufptr, node->value.text.string);
00350
00351 next = node->next;
00352 mxmlDelete(node);
00353 node = next;
00354 }
00355
00356 mxmlElementSetAttr(variable, "default", buffer);
00357 }
00358
00359
00360
00361
00362
00363 if (type->last_child->value.text.string[0] == ')')
00364 {
00365
00366
00367
00368
00369 for (node = type->child; node; node = node->next)
00370 if (node->value.text.string[0] == '(')
00371 break;
00372
00373 for (bufptr = buffer; node; bufptr += strlen(bufptr))
00374 {
00375 if (node->value.text.whitespace && bufptr > buffer)
00376 *bufptr++ = ' ';
00377
00378 strcpy(bufptr, node->value.text.string);
00379
00380 next = node->next;
00381 mxmlDelete(node);
00382 node = next;
00383 }
00384 }
00385 else
00386 {
00387
00388
00389
00390
00391 strcpy(buffer, type->last_child->value.text.string);
00392 mxmlDelete(type->last_child);
00393 }
00394
00395
00396
00397
00398
00399 mxmlElementSetAttr(variable, "name", buffer);
00400
00401
00402
00403
00404
00405 mxmlAdd(variable, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, type);
00406
00407
00408
00409
00410
00411 return (variable);
00412 }
00413
00414
00415
00416
00417
00418
00419 static void
00420 safe_strcpy(char *dst,
00421 const char *src)
00422 {
00423 while (*src)
00424 *dst++ = *src++;
00425
00426 *dst = '\0';
00427 }
00428
00429
00430
00431
00432
00433
00434 static int
00435 scan_file(const char *filename,
00436 FILE *fp,
00437 mxml_node_t *tree)
00438 {
00439 int state,
00440 braces,
00441 parens;
00442 int ch;
00443 char buffer[65536],
00444 *bufptr;
00445 const char *scope;
00446 mxml_node_t *comment,
00447 *constant,
00448 *enumeration,
00449 *function,
00450 *fstructclass,
00451 *structclass,
00452 *typedefnode,
00453 *variable,
00454 *returnvalue,
00455 *type,
00456 *description,
00457 *node,
00458 *next;
00459 #if DEBUG > 1
00460 mxml_node_t *temp;
00461 int oldstate,
00462 oldch;
00463 static const char *states[] =
00464 {
00465 "STATE_NONE",
00466 "STATE_PREPROCESSOR",
00467 "STATE_C_COMMENT",
00468 "STATE_CXX_COMMENT",
00469 "STATE_STRING",
00470 "STATE_CHARACTER",
00471 "STATE_IDENTIFIER"
00472 };
00473 #endif
00474
00475
00476 #ifdef DEBUG
00477 fprintf(stderr, "scan_file(filename=\"%s\", fp=%p, tree=%p)\n", filename,
00478 fp, tree);
00479 #endif // DEBUG
00480
00481
00482
00483
00484
00485 state = STATE_NONE;
00486 braces = 0;
00487 parens = 0;
00488 bufptr = buffer;
00489
00490 comment = mxmlNewElement(MXML_NO_PARENT, "temp");
00491 constant = NULL;
00492 enumeration = NULL;
00493 function = NULL;
00494 variable = NULL;
00495 returnvalue = NULL;
00496 type = NULL;
00497 description = NULL;
00498 typedefnode = NULL;
00499 structclass = NULL;
00500 fstructclass = NULL;
00501
00502 if (!strcmp(tree->value.element.name, "class"))
00503 scope = "private";
00504 else
00505 scope = NULL;
00506
00507
00508
00509
00510
00511 while ((ch = getc(fp)) != EOF)
00512 {
00513 #if DEBUG > 1
00514 oldstate = state;
00515 oldch = ch;
00516 #endif
00517
00518 switch (state)
00519 {
00520 case STATE_NONE :
00521 switch (ch)
00522 {
00523 case '/' :
00524 ch = getc(fp);
00525 bufptr = buffer;
00526
00527 if (ch == '*')
00528 state = STATE_C_COMMENT;
00529 else if (ch == '/')
00530 state = STATE_CXX_COMMENT;
00531 else
00532 {
00533 ungetc(ch, fp);
00534
00535 if (type)
00536 {
00537 #ifdef DEBUG
00538 fputs("Identifier: <<<< / >>>\n", stderr);
00539 #endif
00540 ch = type->last_child->value.text.string[0];
00541 mxmlNewText(type, isalnum(ch) || ch == '_', "/");
00542 }
00543 }
00544 break;
00545
00546 case '#' :
00547 #ifdef DEBUG
00548 fputs(" #preprocessor...\n", stderr);
00549 #endif
00550 state = STATE_PREPROCESSOR;
00551 break;
00552
00553 case '\'' :
00554 state = STATE_CHARACTER;
00555 bufptr = buffer;
00556 *bufptr++ = ch;
00557 break;
00558
00559 case '\"' :
00560 state = STATE_STRING;
00561 bufptr = buffer;
00562 *bufptr++ = ch;
00563 break;
00564
00565 case '{' :
00566 #ifdef DEBUG
00567 fprintf(stderr, " open brace, function=%p, type=%p...\n",
00568 function, type);
00569 if (type)
00570 fprintf(stderr, " type->child=\"%s\"...\n",
00571 type->child->value.text.string);
00572 #endif
00573
00574 if (function)
00575 {
00576 if (fstructclass)
00577 {
00578 sort_node(fstructclass, function);
00579 fstructclass = NULL;
00580 }
00581 else
00582 sort_node(tree, function);
00583
00584 function = NULL;
00585 }
00586 else if (type && type->child &&
00587 ((!strcmp(type->child->value.text.string, "typedef") &&
00588 type->child->next &&
00589 (!strcmp(type->child->next->value.text.string, "struct") ||
00590 !strcmp(type->child->next->value.text.string, "union") ||
00591 !strcmp(type->child->next->value.text.string, "class"))) ||
00592 !strcmp(type->child->value.text.string, "union") ||
00593 !strcmp(type->child->value.text.string, "struct") ||
00594 !strcmp(type->child->value.text.string, "class")))
00595 {
00596
00597
00598
00599
00600 if (!strcmp(type->child->value.text.string, "typedef"))
00601 {
00602 #ifdef DEBUG
00603 fputs(" starting typedef...\n", stderr);
00604 #endif
00605
00606 typedefnode = mxmlNewElement(MXML_NO_PARENT, "typedef");
00607 mxmlDelete(type->child);
00608 }
00609 else
00610 typedefnode = NULL;
00611
00612 structclass = mxmlNewElement(MXML_NO_PARENT,
00613 type->child->value.text.string);
00614
00615 #ifdef DEBUG
00616 fprintf(stderr, "%c%s: <<<< %s >>>\n",
00617 toupper(type->child->value.text.string[0]),
00618 type->child->value.text.string + 1,
00619 type->child->next ?
00620 type->child->next->value.text.string : "(noname)");
00621
00622 fputs(" type =", stderr);
00623 for (node = type->child; node; node = node->next)
00624 fprintf(stderr, " \"%s\"", node->value.text.string);
00625 putc('\n', stderr);
00626
00627 fprintf(stderr, " scope = %s\n", scope ? scope : "(null)");
00628 #endif
00629
00630 if (comment->last_child &&
00631 strstr(comment->last_child->value.text.string, "@private"))
00632 {
00633 mxmlDelete(type);
00634 type = NULL;
00635
00636 if (typedefnode)
00637 {
00638 mxmlDelete(typedefnode);
00639 typedefnode = NULL;
00640 }
00641
00642 mxmlDelete(structclass);
00643 structclass = NULL;
00644
00645 braces ++;
00646 function = NULL;
00647 variable = NULL;
00648 break;
00649 }
00650
00651 if (type->child->next)
00652 {
00653 mxmlElementSetAttr(structclass, "name",
00654 type->child->next->value.text.string);
00655 sort_node(tree, structclass);
00656 }
00657
00658 if (typedefnode && type->child)
00659 type->child->value.text.whitespace = 0;
00660 else if (structclass && type->child &&
00661 type->child->next && type->child->next->next)
00662 {
00663 for (bufptr = buffer, node = type->child->next->next;
00664 node;
00665 bufptr += strlen(bufptr))
00666 {
00667 if (node->value.text.whitespace && bufptr > buffer)
00668 *bufptr++ = ' ';
00669
00670 strcpy(bufptr, node->value.text.string);
00671
00672 next = node->next;
00673 mxmlDelete(node);
00674 node = next;
00675 }
00676
00677 mxmlElementSetAttr(structclass, "parent", buffer);
00678
00679 mxmlDelete(type);
00680 type = NULL;
00681 }
00682 else
00683 {
00684 mxmlDelete(type);
00685 type = NULL;
00686 }
00687
00688 if (typedefnode && comment->last_child)
00689 {
00690
00691
00692
00693
00694 mxmlNewText(comment, 0,
00695 comment->last_child->value.text.string);
00696 description = mxmlNewElement(typedefnode, "description");
00697 #ifdef DEBUG
00698 fputs(" duplicating comment for typedef...\n", stderr);
00699 #endif
00700 update_comment(typedefnode, comment->last_child);
00701 mxmlAdd(description, MXML_ADD_AFTER, MXML_ADD_TO_PARENT,
00702 comment->last_child);
00703 }
00704
00705 description = mxmlNewElement(structclass, "description");
00706 #ifdef DEBUG
00707 fprintf(stderr, " adding comment to %s...\n",
00708 structclass->value.element.name);
00709 #endif
00710 update_comment(structclass, comment->last_child);
00711 mxmlAdd(description, MXML_ADD_AFTER, MXML_ADD_TO_PARENT,
00712 comment->last_child);
00713
00714 if (scan_file(filename, fp, structclass))
00715 {
00716 mxmlDelete(comment);
00717 return (-1);
00718 }
00719
00720 #ifdef DEBUG
00721 fputs(" ended typedef...\n", stderr);
00722 #endif
00723 structclass = NULL;
00724 break;
00725 }
00726 else if (type && type->child && type->child->next &&
00727 (!strcmp(type->child->value.text.string, "enum") ||
00728 (!strcmp(type->child->value.text.string, "typedef") &&
00729 !strcmp(type->child->next->value.text.string, "enum"))))
00730 {
00731
00732
00733
00734
00735 if (!strcmp(type->child->value.text.string, "typedef"))
00736 {
00737 #ifdef DEBUG
00738 fputs(" starting typedef...\n", stderr);
00739 #endif
00740
00741 typedefnode = mxmlNewElement(MXML_NO_PARENT, "typedef");
00742 mxmlDelete(type->child);
00743 }
00744 else
00745 typedefnode = NULL;
00746
00747 enumeration = mxmlNewElement(MXML_NO_PARENT, "enumeration");
00748
00749 #ifdef DEBUG
00750 fprintf(stderr, "Enumeration: <<<< %s >>>\n",
00751 type->child->next ?
00752 type->child->next->value.text.string : "(noname)");
00753 #endif
00754
00755 if (type->child->next)
00756 {
00757 mxmlElementSetAttr(enumeration, "name",
00758 type->child->next->value.text.string);
00759 sort_node(tree, enumeration);
00760 }
00761
00762 if (typedefnode && type->child)
00763 type->child->value.text.whitespace = 0;
00764 else
00765 {
00766 mxmlDelete(type);
00767 type = NULL;
00768 }
00769
00770 if (typedefnode && comment->last_child)
00771 {
00772
00773
00774
00775
00776 mxmlNewText(comment, 0,
00777 comment->last_child->value.text.string);
00778 description = mxmlNewElement(typedefnode, "description");
00779 #ifdef DEBUG
00780 fputs(" duplicating comment for typedef...\n", stderr);
00781 #endif
00782 update_comment(typedefnode, comment->last_child);
00783 mxmlAdd(description, MXML_ADD_AFTER, MXML_ADD_TO_PARENT,
00784 comment->last_child);
00785 }
00786
00787 description = mxmlNewElement(enumeration, "description");
00788 #ifdef DEBUG
00789 fputs(" adding comment to enumeration...\n", stderr);
00790 #endif
00791 update_comment(enumeration, comment->last_child);
00792 mxmlAdd(description, MXML_ADD_AFTER, MXML_ADD_TO_PARENT,
00793 comment->last_child);
00794 }
00795 else if (type && type->child &&
00796 !strcmp(type->child->value.text.string, "extern"))
00797 {
00798 if (scan_file(filename, fp, tree))
00799 {
00800 mxmlDelete(comment);
00801 return (-1);
00802 }
00803 }
00804 else if (type)
00805 {
00806 mxmlDelete(type);
00807 type = NULL;
00808 }
00809
00810 braces ++;
00811 function = NULL;
00812 variable = NULL;
00813 break;
00814
00815 case '}' :
00816 #ifdef DEBUG
00817 fputs(" close brace...\n", stderr);
00818 #endif
00819
00820 if (structclass)
00821 scope = NULL;
00822
00823 enumeration = NULL;
00824 constant = NULL;
00825 structclass = NULL;
00826
00827 if (braces > 0)
00828 braces --;
00829 else
00830 {
00831 mxmlDelete(comment);
00832 return (0);
00833 }
00834 break;
00835
00836 case '(' :
00837 if (type)
00838 {
00839 #ifdef DEBUG
00840 fputs("Identifier: <<<< ( >>>\n", stderr);
00841 #endif
00842 mxmlNewText(type, 0, "(");
00843 }
00844
00845 parens ++;
00846 break;
00847
00848 case ')' :
00849 if (parens > 0)
00850 parens --;
00851
00852 if (type && parens)
00853 {
00854 #ifdef DEBUG
00855 fputs("Identifier: <<<< ) >>>\n", stderr);
00856 #endif
00857 mxmlNewText(type, 0, ")");
00858 }
00859
00860 if (function && type && !parens)
00861 {
00862 variable = add_variable(function, "argument", type);
00863 type = NULL;
00864 }
00865 break;
00866
00867 case ';' :
00868 #ifdef DEBUG
00869 fputs("Identifier: <<<< ; >>>\n", stderr);
00870 fprintf(stderr, " function=%p, type=%p\n", function, type);
00871 #endif
00872
00873 if (function)
00874 {
00875 if (!strcmp(tree->value.element.name, "class"))
00876 {
00877 #ifdef DEBUG
00878 fputs(" ADDING FUNCTION TO CLASS\n", stderr);
00879 #endif
00880 sort_node(tree, function);
00881 }
00882 else
00883 mxmlDelete(function);
00884
00885 function = NULL;
00886 variable = NULL;
00887 }
00888
00889 if (type)
00890 {
00891 mxmlDelete(type);
00892 type = NULL;
00893 }
00894 break;
00895
00896 case ':' :
00897 if (type)
00898 {
00899 #ifdef DEBUG
00900 fputs("Identifier: <<<< : >>>\n", stderr);
00901 #endif
00902 mxmlNewText(type, 1, ":");
00903 }
00904 break;
00905
00906 case '*' :
00907 if (type)
00908 {
00909 #ifdef DEBUG
00910 fputs("Identifier: <<<< * >>>\n", stderr);
00911 #endif
00912 ch = type->last_child->value.text.string[0];
00913 mxmlNewText(type, isalnum(ch) || ch == '_', "*");
00914 }
00915 break;
00916
00917 case '&' :
00918 if (type)
00919 {
00920 #ifdef DEBUG
00921 fputs("Identifier: <<<< & >>>\n", stderr);
00922 #endif
00923 mxmlNewText(type, 1, "&");
00924 }
00925 break;
00926
00927 case '+' :
00928 if (type)
00929 {
00930 #ifdef DEBUG
00931 fputs("Identifier: <<<< + >>>\n", stderr);
00932 #endif
00933 ch = type->last_child->value.text.string[0];
00934 mxmlNewText(type, isalnum(ch) || ch == '_', "+");
00935 }
00936 break;
00937
00938 case '-' :
00939 if (type)
00940 {
00941 #ifdef DEBUG
00942 fputs("Identifier: <<<< - >>>\n", stderr);
00943 #endif
00944 ch = type->last_child->value.text.string[0];
00945 mxmlNewText(type, isalnum(ch) || ch == '_', "-");
00946 }
00947 break;
00948
00949 case '=' :
00950 if (type)
00951 {
00952 #ifdef DEBUG
00953 fputs("Identifier: <<<< = >>>\n", stderr);
00954 #endif
00955 ch = type->last_child->value.text.string[0];
00956 mxmlNewText(type, isalnum(ch) || ch == '_', "=");
00957 }
00958 break;
00959
00960 default :
00961 if (isalnum(ch) || ch == '_' || ch == '.' || ch == ':' || ch == '~')
00962 {
00963 state = STATE_IDENTIFIER;
00964 bufptr = buffer;
00965 *bufptr++ = ch;
00966 }
00967 break;
00968 }
00969 break;
00970
00971 case STATE_PREPROCESSOR :
00972 if (ch == '\n')
00973 state = STATE_NONE;
00974 else if (ch == '\\')
00975 getc(fp);
00976 break;
00977
00978 case STATE_C_COMMENT :
00979 switch (ch)
00980 {
00981 case '\n' :
00982 while ((ch = getc(fp)) != EOF)
00983 if (ch == '*')
00984 {
00985 ch = getc(fp);
00986
00987 if (ch == '/')
00988 {
00989 *bufptr = '\0';
00990
00991 if (comment->child != comment->last_child)
00992 {
00993 #ifdef DEBUG
00994 fprintf(stderr, " removing comment %p, last comment %p...\n",
00995 comment->child, comment->last_child);
00996 #endif
00997 mxmlDelete(comment->child);
00998 #ifdef DEBUG
00999 fprintf(stderr, " new comment %p, last comment %p...\n",
01000 comment->child, comment->last_child);
01001 #endif
01002 }
01003
01004 #ifdef DEBUG
01005 fprintf(stderr, " processing comment, variable=%p, constant=%p, tree=\"%s\"\n",
01006 variable, constant, tree->value.element.name);
01007 #endif
01008
01009 if (variable)
01010 {
01011 description = mxmlNewElement(variable, "description");
01012 #ifdef DEBUG
01013 fputs(" adding comment to variable...\n", stderr);
01014 #endif
01015 update_comment(variable,
01016 mxmlNewText(description, 0, buffer));
01017 variable = NULL;
01018 }
01019 else if (constant)
01020 {
01021 description = mxmlNewElement(constant, "description");
01022 #ifdef DEBUG
01023 fputs(" adding comment to constant...\n", stderr);
01024 #endif
01025 update_comment(constant,
01026 mxmlNewText(description, 0, buffer));
01027 constant = NULL;
01028 }
01029 else if (typedefnode)
01030 {
01031 description = mxmlNewElement(typedefnode, "description");
01032 #ifdef DEBUG
01033 fprintf(stderr, " adding comment to typedef %s...\n",
01034 mxmlElementGetAttr(typedefnode, "name"));
01035 #endif
01036 update_comment(typedefnode,
01037 mxmlNewText(description, 0, buffer));
01038 }
01039 else if (strcmp(tree->value.element.name, "mxmldoc") &&
01040 !mxmlFindElement(tree, tree, "description",
01041 NULL, NULL, MXML_DESCEND_FIRST))
01042 {
01043 description = mxmlNewElement(tree, "description");
01044 #ifdef DEBUG
01045 fputs(" adding comment to parent...\n", stderr);
01046 #endif
01047 update_comment(tree,
01048 mxmlNewText(description, 0, buffer));
01049 }
01050 else
01051 {
01052 #ifdef DEBUG
01053 fprintf(stderr, " before adding comment, child=%p, last_child=%p\n",
01054 comment->child, comment->last_child);
01055 #endif
01056 mxmlNewText(comment, 0, buffer);
01057 #ifdef DEBUG
01058 fprintf(stderr, " after adding comment, child=%p, last_child=%p\n",
01059 comment->child, comment->last_child);
01060 #endif
01061 }
01062 #ifdef DEBUG
01063 fprintf(stderr, "C comment: <<<< %s >>>\n", buffer);
01064 #endif
01065
01066 state = STATE_NONE;
01067 break;
01068 }
01069 else
01070 ungetc(ch, fp);
01071 }
01072 else if (ch == '\n' && bufptr > buffer &&
01073 bufptr < (buffer + sizeof(buffer) - 1))
01074 *bufptr++ = ch;
01075 else if (!isspace(ch))
01076 break;
01077
01078 if (ch != EOF)
01079 ungetc(ch, fp);
01080
01081 if (bufptr > buffer && bufptr < (buffer + sizeof(buffer) - 1))
01082 *bufptr++ = '\n';
01083 break;
01084
01085 case '/' :
01086 if (ch == '/' && bufptr > buffer && bufptr[-1] == '*')
01087 {
01088 while (bufptr > buffer &&
01089 (bufptr[-1] == '*' || isspace(bufptr[-1] & 255)))
01090 bufptr --;
01091 *bufptr = '\0';
01092
01093 if (comment->child != comment->last_child)
01094 {
01095 #ifdef DEBUG
01096 fprintf(stderr, " removing comment %p, last comment %p...\n",
01097 comment->child, comment->last_child);
01098 #endif
01099 mxmlDelete(comment->child);
01100 #ifdef DEBUG
01101 fprintf(stderr, " new comment %p, last comment %p...\n",
01102 comment->child, comment->last_child);
01103 #endif
01104 }
01105
01106 if (variable)
01107 {
01108 description = mxmlNewElement(variable, "description");
01109 #ifdef DEBUG
01110 fputs(" adding comment to variable...\n", stderr);
01111 #endif
01112 update_comment(variable,
01113 mxmlNewText(description, 0, buffer));
01114 variable = NULL;
01115 }
01116 else if (constant)
01117 {
01118 description = mxmlNewElement(constant, "description");
01119 #ifdef DEBUG
01120 fputs(" adding comment to constant...\n", stderr);
01121 #endif
01122 update_comment(constant,
01123 mxmlNewText(description, 0, buffer));
01124 constant = NULL;
01125 }
01126 else if (typedefnode)
01127 {
01128 description = mxmlNewElement(typedefnode, "description");
01129 #ifdef DEBUG
01130 fprintf(stderr, " adding comment to typedef %s...\n",
01131 mxmlElementGetAttr(typedefnode, "name"));
01132 #endif
01133 update_comment(typedefnode,
01134 mxmlNewText(description, 0, buffer));
01135 }
01136 else if (strcmp(tree->value.element.name, "mxmldoc") &&
01137 !mxmlFindElement(tree, tree, "description",
01138 NULL, NULL, MXML_DESCEND_FIRST))
01139 {
01140 description = mxmlNewElement(tree, "description");
01141 #ifdef DEBUG
01142 fputs(" adding comment to parent...\n", stderr);
01143 #endif
01144 update_comment(tree,
01145 mxmlNewText(description, 0, buffer));
01146 }
01147 else
01148 mxmlNewText(comment, 0, buffer);
01149
01150 #ifdef DEBUG
01151 fprintf(stderr, "C comment: <<<< %s >>>\n", buffer);
01152 #endif
01153
01154 state = STATE_NONE;
01155 break;
01156 }
01157
01158 default :
01159 if (ch == ' ' && bufptr == buffer)
01160 break;
01161
01162 if (bufptr < (buffer + sizeof(buffer) - 1))
01163 *bufptr++ = ch;
01164 break;
01165 }
01166 break;
01167
01168 case STATE_CXX_COMMENT :
01169 if (ch == '\n')
01170 {
01171 state = STATE_NONE;
01172 *bufptr = '\0';
01173
01174 if (comment->child != comment->last_child)
01175 {
01176 #ifdef DEBUG
01177 fprintf(stderr, " removing comment %p, last comment %p...\n",
01178 comment->child, comment->last_child);
01179 #endif
01180 mxmlDelete(comment->child);
01181 #ifdef DEBUG
01182 fprintf(stderr, " new comment %p, last comment %p...\n",
01183 comment->child, comment->last_child);
01184 #endif
01185 }
01186
01187 if (variable)
01188 {
01189 description = mxmlNewElement(variable, "description");
01190 #ifdef DEBUG
01191 fputs(" adding comment to variable...\n", stderr);
01192 #endif
01193 update_comment(variable,
01194 mxmlNewText(description, 0, buffer));
01195 variable = NULL;
01196 }
01197 else if (constant)
01198 {
01199 description = mxmlNewElement(constant, "description");
01200 #ifdef DEBUG
01201 fputs(" adding comment to constant...\n", stderr);
01202 #endif
01203 update_comment(constant,
01204 mxmlNewText(description, 0, buffer));
01205 constant = NULL;
01206 }
01207 else if (typedefnode)
01208 {
01209 description = mxmlNewElement(typedefnode, "description");
01210 #ifdef DEBUG
01211 fprintf(stderr, " adding comment to typedef %s...\n",
01212 mxmlElementGetAttr(typedefnode, "name"));
01213 #endif
01214 update_comment(typedefnode,
01215 mxmlNewText(description, 0, buffer));
01216 }
01217 else if (strcmp(tree->value.element.name, "mxmldoc") &&
01218 !mxmlFindElement(tree, tree, "description",
01219 NULL, NULL, MXML_DESCEND_FIRST))
01220 {
01221 description = mxmlNewElement(tree, "description");
01222 #ifdef DEBUG
01223 fputs(" adding comment to parent...\n", stderr);
01224 #endif
01225 update_comment(tree,
01226 mxmlNewText(description, 0, buffer));
01227 }
01228 else
01229 mxmlNewText(comment, 0, buffer);
01230
01231 #ifdef DEBUG
01232 fprintf(stderr, "C++ comment: <<<< %s >>>\n", buffer);
01233 #endif
01234 }
01235 else if (ch == ' ' && bufptr == buffer)
01236 break;
01237 else if (bufptr < (buffer + sizeof(buffer) - 1))
01238 *bufptr++ = ch;
01239 break;
01240
01241 case STATE_STRING :
01242 *bufptr++ = ch;
01243
01244 if (ch == '\\')
01245 *bufptr++ = getc(fp);
01246 else if (ch == '\"')
01247 {
01248 *bufptr = '\0';
01249
01250 if (type)
01251 mxmlNewText(type, type->child != NULL, buffer);
01252
01253 state = STATE_NONE;
01254 }
01255 break;
01256
01257 case STATE_CHARACTER :
01258 *bufptr++ = ch;
01259
01260 if (ch == '\\')
01261 *bufptr++ = getc(fp);
01262 else if (ch == '\'')
01263 {
01264 *bufptr = '\0';
01265
01266 if (type)
01267 mxmlNewText(type, type->child != NULL, buffer);
01268
01269 state = STATE_NONE;
01270 }
01271 break;
01272
01273 case STATE_IDENTIFIER :
01274 if (isalnum(ch) || ch == '_' || ch == '[' || ch == ']' ||
01275 (ch == ',' && parens > 1) || ch == ':' || ch == '.' || ch == '~')
01276 {
01277 if (bufptr < (buffer + sizeof(buffer) - 1))
01278 *bufptr++ = ch;
01279 }
01280 else
01281 {
01282 ungetc(ch, fp);
01283 *bufptr = '\0';
01284 state = STATE_NONE;
01285
01286 #ifdef DEBUG
01287 fprintf(stderr, " braces=%d, type=%p, type->child=%p, buffer=\"%s\"\n",
01288 braces, type, type ? type->child : NULL, buffer);
01289 #endif
01290
01291 if (!braces)
01292 {
01293 if (!type || !type->child)
01294 {
01295 if (!strcmp(tree->value.element.name, "class"))
01296 {
01297 if (!strcmp(buffer, "public") ||
01298 !strcmp(buffer, "public:"))
01299 {
01300 scope = "public";
01301 #ifdef DEBUG
01302 fputs(" scope = public\n", stderr);
01303 #endif
01304 break;
01305 }
01306 else if (!strcmp(buffer, "private") ||
01307 !strcmp(buffer, "private:"))
01308 {
01309 scope = "private";
01310 #ifdef DEBUG
01311 fputs(" scope = private\n", stderr);
01312 #endif
01313 break;
01314 }
01315 else if (!strcmp(buffer, "protected") ||
01316 !strcmp(buffer, "protected:"))
01317 {
01318 scope = "protected";
01319 #ifdef DEBUG
01320 fputs(" scope = protected\n", stderr);
01321 #endif
01322 break;
01323 }
01324 }
01325 }
01326
01327 if (!type)
01328 type = mxmlNewElement(MXML_NO_PARENT, "type");
01329
01330 #ifdef DEBUG
01331 fprintf(stderr, " function=%p (%s), type->child=%p, ch='%c', parens=%d\n",
01332 function,
01333 function ? mxmlElementGetAttr(function, "name") : "null",
01334 type->child, ch, parens);
01335 #endif
01336
01337 if (!function && ch == '(')
01338 {
01339 if (type->child &&
01340 !strcmp(type->child->value.text.string, "extern"))
01341 {
01342
01343
01344
01345
01346 mxmlDelete(type);
01347 type = NULL;
01348 break;
01349 }
01350
01351 if (type->child &&
01352 !strcmp(type->child->value.text.string, "static") &&
01353 !strcmp(tree->value.element.name, "mxmldoc"))
01354 {
01355
01356
01357
01358
01359 mxmlDelete(type);
01360 type = NULL;
01361 break;
01362 }
01363
01364 function = mxmlNewElement(MXML_NO_PARENT, "function");
01365 if ((bufptr = strchr(buffer, ':')) != NULL && bufptr[1] == ':')
01366 {
01367 *bufptr = '\0';
01368 bufptr += 2;
01369
01370 if ((fstructclass =
01371 mxmlFindElement(tree, tree, "class", "name", buffer,
01372 MXML_DESCEND_FIRST)) == NULL)
01373 fstructclass =
01374 mxmlFindElement(tree, tree, "struct", "name", buffer,
01375 MXML_DESCEND_FIRST);
01376 }
01377 else
01378 bufptr = buffer;
01379
01380 mxmlElementSetAttr(function, "name", bufptr);
01381
01382 if (scope)
01383 mxmlElementSetAttr(function, "scope", scope);
01384
01385 #ifdef DEBUG
01386 fprintf(stderr, "function: %s\n", buffer);
01387 fprintf(stderr, " scope = %s\n", scope ? scope : "(null)");
01388 fprintf(stderr, " comment = %p\n", comment);
01389 fprintf(stderr, " child = (%p) %s\n",
01390 comment->child,
01391 comment->child ?
01392 comment->child->value.text.string : "(null)");
01393 fprintf(stderr, " last_child = (%p) %s\n",
01394 comment->last_child,
01395 comment->last_child ?
01396 comment->last_child->value.text.string : "(null)");
01397 #endif
01398
01399 if (type->last_child &&
01400 strcmp(type->last_child->value.text.string, "void"))
01401 {
01402 returnvalue = mxmlNewElement(function, "returnvalue");
01403
01404 mxmlAdd(returnvalue, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, type);
01405
01406 description = mxmlNewElement(returnvalue, "description");
01407 #ifdef DEBUG
01408 fputs(" adding comment to returnvalue...\n", stderr);
01409 #endif
01410 update_comment(returnvalue, comment->last_child);
01411 mxmlAdd(description, MXML_ADD_AFTER, MXML_ADD_TO_PARENT,
01412 comment->last_child);
01413 }
01414 else
01415 mxmlDelete(type);
01416
01417 description = mxmlNewElement(function, "description");
01418 #ifdef DEBUG
01419 fputs(" adding comment to function...\n", stderr);
01420 #endif
01421 update_comment(function, comment->last_child);
01422 mxmlAdd(description, MXML_ADD_AFTER, MXML_ADD_TO_PARENT,
01423 comment->last_child);
01424
01425 type = NULL;
01426 }
01427 else if (function && ((ch == ')' && parens == 1) || ch == ','))
01428 {
01429
01430
01431
01432
01433 mxmlNewText(type, type->child != NULL &&
01434 type->last_child->value.text.string[0] != '(' &&
01435 type->last_child->value.text.string[0] != '*',
01436 buffer);
01437
01438 #ifdef DEBUG
01439 fprintf(stderr, "Argument: <<<< %s >>>\n", buffer);
01440 #endif
01441
01442 variable = add_variable(function, "argument", type);
01443 type = NULL;
01444 }
01445 else if (type->child && !function && (ch == ';' || ch == ','))
01446 {
01447 #ifdef DEBUG
01448 fprintf(stderr, " got semicolon, typedefnode=%p, structclass=%p\n",
01449 typedefnode, structclass);
01450 #endif
01451
01452 if (typedefnode || structclass)
01453 {
01454 #ifdef DEBUG
01455 fprintf(stderr, "Typedef/struct/class: <<<< %s >>>>\n", buffer);
01456 #endif
01457
01458 if (typedefnode)
01459 {
01460 mxmlElementSetAttr(typedefnode, "name", buffer);
01461
01462 sort_node(tree, typedefnode);
01463 }
01464
01465 if (structclass && !mxmlElementGetAttr(structclass, "name"))
01466 {
01467 #ifdef DEBUG
01468 fprintf(stderr, "setting struct/class name to %s!\n",
01469 type->last_child->value.text.string);
01470 #endif
01471 mxmlElementSetAttr(structclass, "name", buffer);
01472
01473 sort_node(tree, structclass);
01474 structclass = NULL;
01475 }
01476
01477 if (typedefnode)
01478 mxmlAdd(typedefnode, MXML_ADD_BEFORE, MXML_ADD_TO_PARENT,
01479 type);
01480 else
01481 mxmlDelete(type);
01482
01483 type = NULL;
01484 typedefnode = NULL;
01485 }
01486 else if (type->child &&
01487 !strcmp(type->child->value.text.string, "typedef"))
01488 {
01489
01490
01491
01492
01493 #ifdef DEBUG
01494 fprintf(stderr, "Typedef: <<<< %s >>>\n", buffer);
01495 #endif
01496
01497 typedefnode = mxmlNewElement(MXML_NO_PARENT, "typedef");
01498 mxmlElementSetAttr(typedefnode, "name", buffer);
01499 mxmlDelete(type->child);
01500
01501 sort_node(tree, typedefnode);
01502
01503 if (type->child)
01504 type->child->value.text.whitespace = 0;
01505
01506 mxmlAdd(typedefnode, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, type);
01507 type = NULL;
01508 }
01509 else if (!parens)
01510 {
01511
01512
01513
01514
01515 if (type->child &&
01516 !strcmp(type->child->value.text.string, "static") &&
01517 !strcmp(tree->value.element.name, "mxmldoc"))
01518 {
01519
01520
01521
01522
01523 mxmlDelete(type);
01524 type = NULL;
01525 break;
01526 }
01527
01528 mxmlNewText(type, type->child != NULL &&
01529 type->last_child->value.text.string[0] != '(' &&
01530 type->last_child->value.text.string[0] != '*',
01531 buffer);
01532
01533 #ifdef DEBUG
01534 fprintf(stderr, "Variable: <<<< %s >>>>\n", buffer);
01535 fprintf(stderr, " scope = %s\n", scope ? scope : "(null)");
01536 #endif
01537
01538 variable = add_variable(MXML_NO_PARENT, "variable", type);
01539 type = NULL;
01540
01541 sort_node(tree, variable);
01542
01543 if (scope)
01544 mxmlElementSetAttr(variable, "scope", scope);
01545 }
01546 }
01547 else
01548 {
01549 #ifdef DEBUG
01550 fprintf(stderr, "Identifier: <<<< %s >>>>\n", buffer);
01551 #endif
01552
01553 mxmlNewText(type, type->child != NULL &&
01554 type->last_child->value.text.string[0] != '(' &&
01555 type->last_child->value.text.string[0] != '*',
01556 buffer);
01557 }
01558 }
01559 else if (enumeration && !isdigit(buffer[0] & 255))
01560 {
01561 #ifdef DEBUG
01562 fprintf(stderr, "Constant: <<<< %s >>>\n", buffer);
01563 #endif
01564
01565 constant = mxmlNewElement(MXML_NO_PARENT, "constant");
01566 mxmlElementSetAttr(constant, "name", buffer);
01567 sort_node(enumeration, constant);
01568 }
01569 else if (type)
01570 {
01571 mxmlDelete(type);
01572 type = NULL;
01573 }
01574 }
01575 break;
01576 }
01577
01578 #if DEBUG > 1
01579 if (state != oldstate)
01580 {
01581 fprintf(stderr, " changed states from %s to %s on receipt of character '%c'...\n",
01582 states[oldstate], states[state], oldch);
01583 fprintf(stderr, " variable = %p\n", variable);
01584 if (type)
01585 {
01586 fputs(" type =", stderr);
01587 for (temp = type->child; temp; temp = temp->next)
01588 fprintf(stderr, " \"%s\"", temp->value.text.string);
01589 fputs("\n", stderr);
01590 }
01591 }
01592 #endif
01593 }
01594
01595 mxmlDelete(comment);
01596
01597
01598
01599
01600
01601 return (0);
01602 }
01603
01604
01605
01606
01607
01608
01609 static void
01610 sort_node(mxml_node_t *tree,
01611 mxml_node_t *node)
01612 {
01613 mxml_node_t *temp;
01614 const char *tempname,
01615 *nodename,
01616 *scope;
01617
01618
01619 #if DEBUG > 1
01620 fprintf(stderr, " sort_node(tree=%p, node=%p)\n", tree, node);
01621 #endif
01622
01623
01624
01625
01626
01627 if (!tree || !node || node->parent == tree)
01628 return;
01629
01630
01631
01632
01633
01634 if ((nodename = mxmlElementGetAttr(node, "name")) == NULL)
01635 return;
01636
01637 #if DEBUG > 1
01638 fprintf(stderr, " nodename=%p (\"%s\")\n", nodename, nodename);
01639 #endif
01640
01641
01642
01643
01644
01645 if ((temp = mxmlFindElement(tree, tree, node->value.element.name,
01646 "name", nodename, MXML_DESCEND_FIRST)) != NULL)
01647 {
01648
01649
01650
01651
01652 if ((scope = mxmlElementGetAttr(temp, "scope")) != NULL &&
01653 mxmlElementGetAttr(node, "scope") == NULL)
01654 {
01655 #ifdef DEBUG
01656 fprintf(stderr, " copying scope %s for %s\n", scope, nodename);
01657 #endif
01658
01659 mxmlElementSetAttr(node, "scope", scope);
01660 }
01661
01662 mxmlDelete(temp);
01663 }
01664
01665
01666
01667
01668
01669 for (temp = tree->child; temp; temp = temp->next)
01670 {
01671 #if DEBUG > 1
01672 fprintf(stderr, " temp=%p\n", temp);
01673 #endif
01674
01675 if ((tempname = mxmlElementGetAttr(temp, "name")) == NULL)
01676 continue;
01677
01678 #if DEBUG > 1
01679 fprintf(stderr, " tempname=%p (\"%s\")\n", tempname, tempname);
01680 #endif
01681
01682 if (strcmp(nodename, tempname) < 0)
01683 break;
01684 }
01685
01686 if (temp)
01687 mxmlAdd(tree, MXML_ADD_BEFORE, temp, node);
01688 else
01689 mxmlAdd(tree, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, node);
01690 }
01691
01692
01693
01694
01695
01696
01697 static void
01698 update_comment(mxml_node_t *parent,
01699 mxml_node_t *comment)
01700 {
01701 char *ptr;
01702
01703
01704 #ifdef DEBUG
01705 fprintf(stderr, "update_comment(parent=%p, comment=%p)\n",
01706 parent, comment);
01707 #endif
01708
01709
01710
01711
01712
01713 if (!parent || !comment)
01714 return;
01715
01716
01717
01718
01719
01720 ptr = comment->value.text.string;
01721
01722 if (*ptr == '\'')
01723 {
01724
01725
01726
01727
01728 for (ptr ++; *ptr && *ptr != '\''; ptr ++);
01729
01730 if (*ptr == '\'')
01731 {
01732 ptr ++;
01733 while (isspace(*ptr & 255))
01734 ptr ++;
01735
01736 if (*ptr == '-')
01737 ptr ++;
01738
01739 while (isspace(*ptr & 255))
01740 ptr ++;
01741
01742 safe_strcpy(comment->value.text.string, ptr);
01743 }
01744 }
01745 else if (!strncmp(ptr, "I ", 2) || !strncmp(ptr, "O ", 2) ||
01746 !strncmp(ptr, "IO ", 3))
01747 {
01748
01749
01750
01751
01752
01753 ptr = strchr(ptr, ' ');
01754 *ptr++ = '\0';
01755
01756 if (!strcmp(parent->value.element.name, "argument"))
01757 mxmlElementSetAttr(parent, "direction", comment->value.text.string);
01758
01759 while (isspace(*ptr & 255))
01760 ptr ++;
01761
01762 if (*ptr == '-')
01763 ptr ++;
01764
01765 while (isspace(*ptr & 255))
01766 ptr ++;
01767
01768 safe_strcpy(comment->value.text.string, ptr);
01769 }
01770
01771
01772
01773
01774
01775 for (ptr = comment->value.text.string; *ptr == '*'; ptr ++);
01776 for (; isspace(*ptr & 255); ptr ++);
01777 if (ptr > comment->value.text.string)
01778 safe_strcpy(comment->value.text.string, ptr);
01779
01780 for (ptr = comment->value.text.string + strlen(comment->value.text.string) - 1;
01781 ptr > comment->value.text.string && *ptr == '*';
01782 ptr --)
01783 *ptr = '\0';
01784 for (; ptr > comment->value.text.string && isspace(*ptr & 255); ptr --)
01785 *ptr = '\0';
01786
01787 #ifdef DEBUG
01788 fprintf(stderr, " updated comment = %s\n", comment->value.text.string);
01789 #endif
01790 }
01791
01792
01793
01794
01795
01796
01797 static void
01798 write_documentation(mxml_node_t *doc)
01799 {
01800 int i;
01801 mxml_node_t *function,
01802 *scut,
01803 *arg,
01804 *description,
01805 *type;
01806 const char *name,
01807 *cname,
01808 *defval,
01809 *parent;
01810 int inscope;
01811 char prefix;
01812 static const char * const scopes[] =
01813 {
01814 "private",
01815 "protected",
01816 "public"
01817 };
01818
01819
01820
01821
01822
01823
01824 puts("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" "
01825 "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
01826 "<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>\n"
01827 "<head>\n"
01828 "\t<title>Documentation</title>\n"
01829 "\t<meta name='creator' content='" MXML_VERSION "'/>\n"
01830 "\t<style><!--\n"
01831 "\th1, h2, h3, p { font-family: sans-serif; text-align: justify; }\n"
01832 "\ttt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }\n"
01833 "\tpre { font-weight: bold; color: #7f0000; margin-left: 2em; }\n"
01834 "\t--></style>\n"
01835 "</head>\n"
01836 "<body>");
01837
01838
01839
01840
01841
01842 puts("<h2>Contents</h2>");
01843 puts("<ul>");
01844 if (mxmlFindElement(doc, doc, "class", NULL, NULL, MXML_DESCEND_FIRST))
01845 puts("\t<li><a href='#_classes'>Classes</a></li>");
01846 if (mxmlFindElement(doc, doc, "enumeration", NULL, NULL, MXML_DESCEND_FIRST))
01847 puts("\t<li><a href='#_enumerations'>Enumerations</a></li>");
01848 if (mxmlFindElement(doc, doc, "function", NULL, NULL, MXML_DESCEND_FIRST))
01849 puts("\t<li><a href='#_functions'>Functions</a></li>");
01850 if (mxmlFindElement(doc, doc, "struct", NULL, NULL, MXML_DESCEND_FIRST))
01851 puts("\t<li><a href='#_structures'>Structures</a></li>");
01852 if (mxmlFindElement(doc, doc, "typedef", NULL, NULL, MXML_DESCEND_FIRST))
01853 puts("\t<li><a href='#_types'>Types</a></li>");
01854 if (mxmlFindElement(doc, doc, "union", NULL, NULL, MXML_DESCEND_FIRST))
01855 puts("\t<li><a href='#_unions'>Unions</a></li>");
01856 if (mxmlFindElement(doc, doc, "variable", NULL, NULL, MXML_DESCEND_FIRST))
01857 puts("\t<li><a href='#_variables'>Variables</a></li>");
01858 puts("</ul>");
01859
01860
01861
01862
01863
01864 if (mxmlFindElement(doc, doc, "class", NULL, NULL, MXML_DESCEND_FIRST))
01865 {
01866 puts("<!-- NEW PAGE -->\n"
01867 "<h2><a name='_classes'>Classes</a></h2>\n"
01868 "<ul>");
01869
01870 for (scut = mxmlFindElement(doc, doc, "class", NULL, NULL,
01871 MXML_DESCEND_FIRST);
01872 scut;
01873 scut = mxmlFindElement(scut, doc, "class", NULL, NULL,
01874 MXML_NO_DESCEND))
01875 {
01876 name = mxmlElementGetAttr(scut, "name");
01877 printf("\t<li><a href='#%s'><tt>%s</tt></a></li>\n", name, name);
01878 }
01879
01880 puts("</ul>");
01881
01882 for (scut = mxmlFindElement(doc, doc, "class", NULL, NULL,
01883 MXML_DESCEND_FIRST);
01884 scut;
01885 scut = mxmlFindElement(scut, doc, "class", NULL, NULL,
01886 MXML_NO_DESCEND))
01887 {
01888 cname = mxmlElementGetAttr(scut, "name");
01889 printf("<!-- NEW PAGE -->\n"
01890 "<h3><a name='%s'>%s</a></h3>\n"
01891 "<hr noshade/>\n", cname, cname);
01892
01893 description = mxmlFindElement(scut, scut, "description", NULL,
01894 NULL, MXML_DESCEND_FIRST);
01895 if (description)
01896 {
01897 fputs("<h4>Description</h4>\n"
01898 "<p>", stdout);
01899 write_element(NULL, description);
01900 puts("</p>");
01901 }
01902
01903 printf("<h4>Definition</h4>\n"
01904 "<pre>\n"
01905 "class %s", cname);
01906 if ((parent = mxmlElementGetAttr(scut, "parent")) != NULL)
01907 printf(" %s", parent);
01908 puts("\n{");
01909
01910 for (i = 0; i < 3; i ++)
01911 {
01912 inscope = 0;
01913
01914 for (arg = mxmlFindElement(scut, scut, "variable", "scope", scopes[i],
01915 MXML_DESCEND_FIRST);
01916 arg;
01917 arg = mxmlFindElement(arg, scut, "variable", "scope", scopes[i],
01918 MXML_NO_DESCEND))
01919 {
01920 if (!inscope)
01921 {
01922 inscope = 1;
01923 printf(" %s:\n", scopes[i]);
01924 }
01925
01926 printf(" ");
01927 write_element(doc, mxmlFindElement(arg, arg, "type", NULL,
01928 NULL, MXML_DESCEND_FIRST));
01929 printf(" %s;\n", mxmlElementGetAttr(arg, "name"));
01930 }
01931
01932 for (function = mxmlFindElement(scut, scut, "function", "scope", scopes[i],
01933 MXML_DESCEND_FIRST);
01934 function;
01935 function = mxmlFindElement(function, scut, "function", "scope", scopes[i],
01936 MXML_NO_DESCEND))
01937 {
01938 if (!inscope)
01939 {
01940 inscope = 1;
01941 printf(" %s:\n", scopes[i]);
01942 }
01943
01944 name = mxmlElementGetAttr(function, "name");
01945
01946 printf(" ");
01947
01948 arg = mxmlFindElement(function, function, "returnvalue", NULL,
01949 NULL, MXML_DESCEND_FIRST);
01950
01951 if (arg)
01952 {
01953 write_element(doc, mxmlFindElement(arg, arg, "type", NULL,
01954 NULL, MXML_DESCEND_FIRST));
01955 putchar(' ');
01956 }
01957 else if (strcmp(cname, name) && strcmp(cname, name + 1))
01958 fputs("void ", stdout);
01959
01960 printf("<a href='#%s.%s'>%s</a>", cname, name, name);
01961
01962 for (arg = mxmlFindElement(function, function, "argument", NULL, NULL,
01963 MXML_DESCEND_FIRST), prefix = '(';
01964 arg;
01965 arg = mxmlFindElement(arg, function, "argument", NULL, NULL,
01966 MXML_NO_DESCEND), prefix = ',')
01967 {
01968 type = mxmlFindElement(arg, arg, "type", NULL, NULL,
01969 MXML_DESCEND_FIRST);
01970
01971 putchar(prefix);
01972 if (prefix == ',')
01973 putchar(' ');
01974
01975 if (type->child)
01976 {
01977 write_element(doc, type);
01978 putchar(' ');
01979 }
01980 fputs(mxmlElementGetAttr(arg, "name"), stdout);
01981 if ((defval = mxmlElementGetAttr(arg, "default")) != NULL)
01982 printf(" %s", defval);
01983 }
01984
01985 if (prefix == '(')
01986 puts("(void);");
01987 else
01988 puts(");");
01989 }
01990 }
01991
01992 puts("};\n</pre>\n"
01993 "<h4>Members</h4>\n"
01994 "<p class='table'><table align='center' border='1' "
01995 "cellpadding='5' cellspacing='0' width='80%'>\n"
01996 "<thead><tr bgcolor='#cccccc'><th>Name</th><th>Description</th></tr></thead>\n"
01997 "<tbody>");
01998
01999 for (arg = mxmlFindElement(scut, scut, "variable", NULL, NULL,
02000 MXML_DESCEND_FIRST);
02001 arg;
02002 arg = mxmlFindElement(arg, scut, "variable", NULL, NULL,
02003 MXML_NO_DESCEND))
02004 {
02005 printf("<tr><td><tt>%s</tt></td><td>", mxmlElementGetAttr(arg, "name"));
02006
02007 write_element(NULL, mxmlFindElement(arg, arg, "description", NULL,
02008 NULL, MXML_DESCEND_FIRST));
02009
02010 puts("</td></tr>");
02011 }
02012
02013 for (function = mxmlFindElement(scut, scut, "function", NULL, NULL,
02014 MXML_DESCEND_FIRST);
02015 function;
02016 function = mxmlFindElement(function, scut, "function", NULL, NULL,
02017 MXML_NO_DESCEND))
02018 {
02019 name = mxmlElementGetAttr(function, "name");
02020
02021 printf("<tr><td><tt><a name='%s.%s'>%s()</a></tt></td><td>",
02022 cname, name, name);
02023
02024 description = mxmlFindElement(function, function, "description", NULL,
02025 NULL, MXML_DESCEND_FIRST);
02026 if (description)
02027 write_element(NULL, description);
02028
02029 arg = mxmlFindElement(function, function, "returnvalue", NULL,
02030 NULL, MXML_DESCEND_FIRST);
02031
02032 if (arg)
02033 {
02034 fputs("\n<i>Returns:</i> ", stdout);
02035 write_element(NULL, mxmlFindElement(arg, arg, "description", NULL,
02036 NULL, MXML_DESCEND_FIRST));
02037 }
02038
02039 puts("</td></tr>");
02040 }
02041
02042 puts("</tbody></table></p>");
02043 }
02044 }
02045
02046
02047
02048
02049
02050 if (mxmlFindElement(doc, doc, "enumeration", NULL, NULL, MXML_DESCEND_FIRST))
02051 {
02052 puts("<!-- NEW PAGE -->\n"
02053 "<h2><a name='_enumerations'>Enumerations</a></h2>\n"
02054 "<ul>");
02055
02056 for (scut = mxmlFindElement(doc, doc, "enumeration", NULL, NULL,
02057 MXML_DESCEND_FIRST);
02058 scut;
02059 scut = mxmlFindElement(scut, doc, "enumeration", NULL, NULL,
02060 MXML_NO_DESCEND))
02061 {
02062 name = mxmlElementGetAttr(scut, "name");
02063 printf("\t<li><a href='#%s'><tt>%s</tt></a></li>\n", name, name);
02064 }
02065
02066 puts("</ul>");
02067
02068 for (scut = mxmlFindElement(doc, doc, "enumeration", NULL, NULL,
02069 MXML_DESCEND_FIRST);
02070 scut;
02071 scut = mxmlFindElement(scut, doc, "enumeration", NULL, NULL,
02072 MXML_NO_DESCEND))
02073 {
02074 name = mxmlElementGetAttr(scut, "name");
02075 printf("<!-- NEW PAGE -->\n"
02076 "<h3><a name='%s'>%s</a></h3>\n"
02077 "<hr noshade/>\n", name, name);
02078
02079 description = mxmlFindElement(scut, scut, "description", NULL,
02080 NULL, MXML_DESCEND_FIRST);
02081 if (description)
02082 {
02083 fputs("<h4>Description</h4>\n"
02084 "<p>", stdout);
02085 write_element(NULL, description);
02086 puts("</p>");
02087 }
02088
02089 puts("<h4>Values</h4>\n"
02090 "<p class='table'><table align='center' border='1' width='80%' "
02091 "cellpadding='5' cellspacing='0' width='80%'>\n"
02092 "<thead><tr bgcolor='#cccccc'><th>Name</th><th>Description</th></tr></thead>\n"
02093 "<tbody>");
02094
02095 for (arg = mxmlFindElement(scut, scut, "constant", NULL, NULL,
02096 MXML_DESCEND_FIRST);
02097 arg;
02098 arg = mxmlFindElement(arg, scut, "constant", NULL, NULL,
02099 MXML_NO_DESCEND))
02100 {
02101 printf("<tr><td><tt>%s</tt></td><td>", mxmlElementGetAttr(arg, "name"));
02102
02103 write_element(doc, mxmlFindElement(arg, arg, "description", NULL,
02104 NULL, MXML_DESCEND_FIRST));
02105
02106 puts("</td></tr>");
02107 }
02108
02109 puts("</tbody></table></p>");
02110 }
02111 }
02112
02113
02114
02115
02116
02117 if (mxmlFindElement(doc, doc, "function", NULL, NULL, MXML_DESCEND_FIRST))
02118 {
02119 puts("<!-- NEW PAGE -->\n"
02120 "<h2><a name='_functions'>Functions</a></h2>\n"
02121 "<ul>");
02122
02123 for (function = mxmlFindElement(doc, doc, "function", NULL, NULL,
02124 MXML_DESCEND_FIRST);
02125 function;
02126 function = mxmlFindElement(function, doc, "function", NULL, NULL,
02127 MXML_NO_DESCEND))
02128 {
02129 name = mxmlElementGetAttr(function, "name");
02130 printf("\t<li><a href='#%s'><tt>%s()</tt></a></li>\n", name, name);
02131 }
02132
02133 puts("</ul>");
02134
02135 for (function = mxmlFindElement(doc, doc, "function", NULL, NULL,
02136 MXML_DESCEND_FIRST);
02137 function;
02138 function = mxmlFindElement(function, doc, "function", NULL, NULL,
02139 MXML_NO_DESCEND))
02140 {
02141 name = mxmlElementGetAttr(function, "name");
02142 printf("<!-- NEW PAGE -->\n"
02143 "<h3><a name='%s'>%s()</a></h3>\n"
02144 "<hr noshade/>\n", name, name);
02145
02146 description = mxmlFindElement(function, function, "description", NULL,
02147 NULL, MXML_DESCEND_FIRST);
02148 if (description)
02149 {
02150 fputs("<h4>Description</h4>\n"
02151 "<p>", stdout);
02152 write_element(NULL, description);
02153 puts("</p>");
02154 }
02155
02156 puts("<h4>Syntax</h4>\n"
02157 "<pre>");
02158
02159 arg = mxmlFindElement(function, function, "returnvalue", NULL,
02160 NULL, MXML_DESCEND_FIRST);
02161
02162 if (arg)
02163 write_element(doc, mxmlFindElement(arg, arg, "type", NULL,
02164 NULL, MXML_DESCEND_FIRST));
02165 else
02166 fputs("void", stdout);
02167
02168 printf("\n%s", name);
02169 for (arg = mxmlFindElement(function, function, "argument", NULL, NULL,
02170 MXML_DESCEND_FIRST), prefix = '(';
02171 arg;
02172 arg = mxmlFindElement(arg, function, "argument", NULL, NULL,
02173 MXML_NO_DESCEND), prefix = ',')
02174 {
02175 type = mxmlFindElement(arg, arg, "type", NULL, NULL,
02176 MXML_DESCEND_FIRST);
02177
02178 printf("%c\n ", prefix);
02179 if (type->child)
02180 {
02181 write_element(doc, type);
02182 putchar(' ');
02183 }
02184 fputs(mxmlElementGetAttr(arg, "name"), stdout);
02185 if ((defval = mxmlElementGetAttr(arg, "default")) != NULL)
02186 printf(" %s", defval);
02187 }
02188
02189 if (prefix == '(')
02190 puts("(void);\n</pre>");
02191 else
02192 puts(");\n</pre>");
02193
02194 puts("<h4>Arguments</h4>");
02195
02196 if (prefix == '(')
02197 puts("<p>None.</p>");
02198 else
02199 {
02200 puts("<p class='table'><table align='center' border='1' width='80%' "
02201 "cellpadding='5' cellspacing='0' width='80%'>\n"
02202 "<thead><tr bgcolor='#cccccc'><th>Name</th><th>Description</th></tr></thead>\n"
02203 "<tbody>");
02204
02205 for (arg = mxmlFindElement(function, function, "argument", NULL, NULL,
02206 MXML_DESCEND_FIRST);
02207 arg;
02208 arg = mxmlFindElement(arg, function, "argument", NULL, NULL,
02209 MXML_NO_DESCEND))
02210 {
02211 printf("<tr><td><tt>%s</tt></td><td>", mxmlElementGetAttr(arg, "name"));
02212
02213 write_element(NULL, mxmlFindElement(arg, arg, "description", NULL,
02214 NULL, MXML_DESCEND_FIRST));
02215
02216 puts("</td></tr>");
02217 }
02218
02219 puts("</tbody></table></p>");
02220 }
02221
02222 puts("<h4>Returns</h4>");
02223
02224 arg = mxmlFindElement(function, function, "returnvalue", NULL,
02225 NULL, MXML_DESCEND_FIRST);
02226
02227 if (!arg)
02228 puts("<p>Nothing.</p>");
02229 else
02230 {
02231 fputs("<p>", stdout);
02232 write_element(NULL, mxmlFindElement(arg, arg, "description", NULL,
02233 NULL, MXML_DESCEND_FIRST));
02234 puts("</p>");
02235 }
02236 }
02237 }
02238
02239
02240
02241
02242
02243 if (mxmlFindElement(doc, doc, "struct", NULL, NULL, MXML_DESCEND_FIRST))
02244 {
02245 puts("<!-- NEW PAGE -->\n"
02246 "<h2><a name='_structures'>Structures</a></h2>\n"
02247 "<ul>");
02248
02249 for (scut = mxmlFindElement(doc, doc, "struct", NULL, NULL,
02250 MXML_DESCEND_FIRST);
02251 scut;
02252 scut = mxmlFindElement(scut, doc, "struct", NULL, NULL,
02253 MXML_NO_DESCEND))
02254 {
02255 name = mxmlElementGetAttr(scut, "name");
02256 printf("\t<li><a href='#%s'><tt>%s</tt></a></li>\n", name, name);
02257 }
02258
02259 puts("</ul>");
02260
02261 for (scut = mxmlFindElement(doc, doc, "struct", NULL, NULL,
02262 MXML_DESCEND_FIRST);
02263 scut;
02264 scut = mxmlFindElement(scut, doc, "struct", NULL, NULL,
02265 MXML_NO_DESCEND))
02266 {
02267 cname = mxmlElementGetAttr(scut, "name");
02268 printf("<!-- NEW PAGE -->\n"
02269 "<h3><a name='%s'>%s</a></h3>\n"
02270 "<hr noshade/>\n", cname, cname);
02271
02272 description = mxmlFindElement(scut, scut, "description", NULL,
02273 NULL, MXML_DESCEND_FIRST);
02274 if (description)
02275 {
02276 fputs("<h4>Description</h4>\n"
02277 "<p>", stdout);
02278 write_element(NULL, description);
02279 puts("</p>");
02280 }
02281
02282 printf("<h4>Definition</h4>\n"
02283 "<pre>\n"
02284 "struct %s\n{\n", cname);
02285 for (arg = mxmlFindElement(scut, scut, "variable", NULL, NULL,
02286 MXML_DESCEND_FIRST);
02287 arg;
02288 arg = mxmlFindElement(arg, scut, "variable", NULL, NULL,
02289 MXML_NO_DESCEND))
02290 {
02291 printf(" ");
02292 write_element(doc, mxmlFindElement(arg, arg, "type", NULL,
02293 NULL, MXML_DESCEND_FIRST));
02294 printf(" %s;\n", mxmlElementGetAttr(arg, "name"));
02295 }
02296
02297 for (function = mxmlFindElement(scut, scut, "function", NULL, NULL,
02298 MXML_DESCEND_FIRST);
02299 function;
02300 function = mxmlFindElement(function, scut, "function", NULL, NULL,
02301 MXML_NO_DESCEND))
02302 {
02303 name = mxmlElementGetAttr(function, "name");
02304
02305 printf(" ");
02306
02307 arg = mxmlFindElement(function, function, "returnvalue", NULL,
02308 NULL, MXML_DESCEND_FIRST);
02309
02310 if (arg)
02311 {
02312 write_element(doc, mxmlFindElement(arg, arg, "type", NULL,
02313 NULL, MXML_DESCEND_FIRST));
02314 putchar(' ');
02315 }
02316 else if (strcmp(cname, name) && strcmp(cname, name + 1))
02317 fputs("void ", stdout);
02318
02319 printf("<a href='#%s.%s'>%s</a>", cname, name, name);
02320
02321 for (arg = mxmlFindElement(function, function, "argument", NULL, NULL,
02322 MXML_DESCEND_FIRST), prefix = '(';
02323 arg;
02324 arg = mxmlFindElement(arg, function, "argument", NULL, NULL,
02325 MXML_NO_DESCEND), prefix = ',')
02326 {
02327 type = mxmlFindElement(arg, arg, "type", NULL, NULL,
02328 MXML_DESCEND_FIRST);
02329
02330 putchar(prefix);
02331 if (prefix == ',')
02332 putchar(' ');
02333
02334 if (type->child)
02335 {
02336 write_element(doc, type);
02337 putchar(' ');
02338 }
02339 fputs(mxmlElementGetAttr(arg, "name"), stdout);
02340 if ((defval = mxmlElementGetAttr(arg, "default")) != NULL)
02341 printf(" %s", defval);
02342 }
02343
02344 if (prefix == '(')
02345 puts("(void);");
02346 else
02347 puts(");");
02348 }
02349
02350 puts("};\n</pre>\n"
02351 "<h4>Members</h4>\n"
02352 "<p class='table'><table align='center' border='1' width='80%' "
02353 "cellpadding='5' cellspacing='0' width='80%'>\n"
02354 "<thead><tr bgcolor='#cccccc'><th>Name</th><th>Description</th></tr></thead>\n"
02355 "<tbody>");
02356
02357 for (arg = mxmlFindElement(scut, scut, "variable", NULL, NULL,
02358 MXML_DESCEND_FIRST);
02359 arg;
02360 arg = mxmlFindElement(arg, scut, "variable", NULL, NULL,
02361 MXML_NO_DESCEND))
02362 {
02363 printf("<tr><td><tt>%s</tt></td><td>", mxmlElementGetAttr(arg, "name"));
02364
02365 write_element(NULL, mxmlFindElement(arg, arg, "description", NULL,
02366 NULL, MXML_DESCEND_FIRST));
02367
02368 puts("</td></tr>");
02369 }
02370
02371 for (function = mxmlFindElement(scut, scut, "function", NULL, NULL,
02372 MXML_DESCEND_FIRST);
02373 function;
02374 function = mxmlFindElement(function, scut, "function", NULL, NULL,
02375 MXML_NO_DESCEND))
02376 {
02377 name = mxmlElementGetAttr(function, "name");
02378
02379 printf("<tr><td><tt><a name='%s.%s'>%s()</a></tt></td><td>",
02380 cname, name, name);
02381
02382 description = mxmlFindElement(function, function, "description", NULL,
02383 NULL, MXML_DESCEND_FIRST);
02384 if (description)
02385 write_element(NULL, description);
02386
02387 arg = mxmlFindElement(function, function, "returnvalue", NULL,
02388 NULL, MXML_DESCEND_FIRST);
02389
02390 if (arg)
02391 {
02392 fputs("\n<i>Returns:</i> ", stdout);
02393 write_element(NULL, mxmlFindElement(arg, arg, "description", NULL,
02394 NULL, MXML_DESCEND_FIRST));
02395 }
02396
02397 puts("</td></tr>");
02398 }
02399
02400 puts("</tbody></table></p>");
02401 }
02402 }
02403
02404
02405
02406
02407
02408 if (mxmlFindElement(doc, doc, "typedef", NULL, NULL, MXML_DESCEND_FIRST))
02409 {
02410 puts("<!-- NEW PAGE -->\n"
02411 "<h2><a name='_types'>Types</a></h2>\n"
02412 "<ul>");
02413
02414 for (scut = mxmlFindElement(doc, doc, "typedef", NULL, NULL,
02415 MXML_DESCEND_FIRST);
02416 scut;
02417 scut = mxmlFindElement(scut, doc, "typedef", NULL, NULL,
02418 MXML_NO_DESCEND))
02419 {
02420 name = mxmlElementGetAttr(scut, "name");
02421 printf("\t<li><a href='#%s'><tt>%s</tt></a></li>\n", name, name);
02422 }
02423
02424 puts("</ul>");
02425
02426 for (scut = mxmlFindElement(doc, doc, "typedef", NULL, NULL,
02427 MXML_DESCEND_FIRST);
02428 scut;
02429 scut = mxmlFindElement(scut, doc, "typedef", NULL, NULL,
02430 MXML_NO_DESCEND))
02431 {
02432 name = mxmlElementGetAttr(scut, "name");
02433 printf("<!-- NEW PAGE -->\n"
02434 "<h3><a name='%s'>%s</a></h3>\n"
02435 "<hr noshade/>\n", name, name);
02436
02437 description = mxmlFindElement(scut, scut, "description", NULL,
02438 NULL, MXML_DESCEND_FIRST);
02439 if (description)
02440 {
02441 fputs("<h4>Description</h4>\n"
02442 "<p>", stdout);
02443 write_element(NULL, description);
02444 puts("</p>");
02445 }
02446
02447 fputs("<h4>Definition</h4>\n"
02448 "<pre>\n"
02449 "typedef ", stdout);
02450 write_element(doc, mxmlFindElement(scut, scut, "type", NULL,
02451 NULL, MXML_DESCEND_FIRST));
02452 printf(" %s;\n</pre>\n", name);
02453 }
02454 }
02455
02456
02457
02458
02459
02460 if (mxmlFindElement(doc, doc, "union", NULL, NULL, MXML_DESCEND_FIRST))
02461 {
02462 puts("<!-- NEW PAGE -->\n"
02463 "<h2><a name='_unions'>Unions</a></h2>\n"
02464 "<ul>");
02465
02466 for (scut = mxmlFindElement(doc, doc, "union", NULL, NULL,
02467 MXML_DESCEND_FIRST);
02468 scut;
02469 scut = mxmlFindElement(scut, doc, "union", NULL, NULL,
02470 MXML_NO_DESCEND))
02471 {
02472 name = mxmlElementGetAttr(scut, "name");
02473 printf("\t<li><a href='#%s'><tt>%s</tt></a></li>\n", name, name);
02474 }
02475
02476 puts("</ul>");
02477
02478 for (scut = mxmlFindElement(doc, doc, "union", NULL, NULL,
02479 MXML_DESCEND_FIRST);
02480 scut;
02481 scut = mxmlFindElement(scut, doc, "union", NULL, NULL,
02482 MXML_NO_DESCEND))
02483 {
02484 name = mxmlElementGetAttr(scut, "name");
02485 printf("<!-- NEW PAGE -->\n"
02486 "<h3><a name='%s'>%s</a></h3>\n"
02487 "<hr noshade/>\n", name, name);
02488
02489 description = mxmlFindElement(scut, scut, "description", NULL,
02490 NULL, MXML_DESCEND_FIRST);
02491 if (description)
02492 {
02493 fputs("<h4>Description</h4>\n"
02494 "<p>", stdout);
02495 write_element(NULL, description);
02496 puts("</p>");
02497 }
02498
02499 printf("<h4>Definition</h4>\n"
02500 "<pre>\n"
02501 "union %s\n{\n", name);
02502 for (arg = mxmlFindElement(scut, scut, "variable", NULL, NULL,
02503 MXML_DESCEND_FIRST);
02504 arg;
02505 arg = mxmlFindElement(arg, scut, "variable", NULL, NULL,
02506 MXML_NO_DESCEND))
02507 {
02508 printf(" ");
02509 write_element(doc, mxmlFindElement(arg, arg, "type", NULL,
02510 NULL, MXML_DESCEND_FIRST));
02511 printf(" %s;\n", mxmlElementGetAttr(arg, "name"));
02512 }
02513
02514 puts("};\n</pre>\n"
02515 "<h4>Members</h4>\n"
02516 "<p class='table'><table align='center' border='1' width='80%' "
02517 "cellpadding='5' cellspacing='0' width='80%'>\n"
02518 "<thead><tr bgcolor='#cccccc'><th>Name</th><th>Description</th></tr></thead>\n"
02519 "<tbody>");
02520
02521 for (arg = mxmlFindElement(scut, scut, "variable", NULL, NULL,
02522 MXML_DESCEND_FIRST);
02523 arg;
02524 arg = mxmlFindElement(arg, scut, "variable", NULL, NULL,
02525 MXML_NO_DESCEND))
02526 {
02527 printf("<tr><td><tt>%s</tt></td><td>", mxmlElementGetAttr(arg, "name"));
02528
02529 write_element(NULL, mxmlFindElement(arg, arg, "description", NULL,
02530 NULL, MXML_DESCEND_FIRST));
02531
02532 puts("</td></tr>");
02533 }
02534
02535 puts("</tbody></table></p>");
02536 }
02537 }
02538
02539
02540
02541
02542
02543 if (mxmlFindElement(doc, doc, "variable", NULL, NULL, MXML_DESCEND_FIRST))
02544 {
02545 puts("<!-- NEW PAGE -->\n"
02546 "<h2><a name='_variables'>Variables</a></h2>\n"
02547 "<ul>");
02548
02549 for (arg = mxmlFindElement(doc, doc, "variable", NULL, NULL,
02550 MXML_DESCEND_FIRST);
02551 arg;
02552 arg = mxmlFindElement(arg, doc, "variable", NULL, NULL,
02553 MXML_NO_DESCEND))
02554 {
02555 name = mxmlElementGetAttr(arg, "name");
02556 printf("\t<li><a href='#%s'><tt>%s</tt></a></li>\n", name, name);
02557 }
02558
02559 puts("</ul>");
02560
02561 for (arg = mxmlFindElement(doc, doc, "variable", NULL, NULL,
02562 MXML_DESCEND_FIRST);
02563 arg;
02564 arg = mxmlFindElement(arg, doc, "variable", NULL, NULL,
02565 MXML_NO_DESCEND))
02566 {
02567 name = mxmlElementGetAttr(arg, "name");
02568 printf("<!-- NEW PAGE -->\n"
02569 "<h3><a name='%s'>%s</a></h3>\n"
02570 "<hr noshade/>", name, name);
02571
02572 description = mxmlFindElement(arg, arg, "description", NULL,
02573 NULL, MXML_DESCEND_FIRST);
02574 if (description)
02575 {
02576 fputs("<h4>Description</h4>\n"
02577 "<p>", stdout);
02578 write_element(NULL, description);
02579 puts("</p>");
02580 }
02581
02582 puts("<h4>Definition</h4>\n"
02583 "<pre>");
02584
02585 write_element(doc, mxmlFindElement(arg, arg, "type", NULL,
02586 NULL, MXML_DESCEND_FIRST));
02587 printf(" %s", mxmlElementGetAttr(arg, "name"));
02588 if ((defval = mxmlElementGetAttr(arg, "default")) != NULL)
02589 printf(" %s", defval);
02590 puts(";\n</pre>");
02591 }
02592 }
02593
02594
02595
02596
02597
02598 puts("</body>\n"
02599 "</html>");
02600 }
02601
02602
02603
02604
02605
02606
02607 static void
02608 write_element(mxml_node_t *doc,
02609 mxml_node_t *element)
02610 {
02611 mxml_node_t *node;
02612
02613
02614 if (!element)
02615 return;
02616
02617 for (node = element->child;
02618 node;
02619 node = mxmlWalkNext(node, element, MXML_NO_DESCEND))
02620 if (node->type == MXML_TEXT)
02621 {
02622 if (node->value.text.whitespace)
02623 putchar(' ');
02624
02625 if (mxmlFindElement(doc, doc, "class", "name", node->value.text.string,
02626 MXML_DESCEND) ||
02627 mxmlFindElement(doc, doc, "enumeration", "name",
02628 node->value.text.string, MXML_DESCEND) ||
02629 mxmlFindElement(doc, doc, "struct", "name", node->value.text.string,
02630 MXML_DESCEND) ||
02631 mxmlFindElement(doc, doc, "typedef", "name", node->value.text.string,
02632 MXML_DESCEND) ||
02633 mxmlFindElement(doc, doc, "union", "name", node->value.text.string,
02634 MXML_DESCEND))
02635 {
02636 printf("<a href='#");
02637 write_string(node->value.text.string);
02638 printf("'>");
02639 write_string(node->value.text.string);
02640 printf("</a>");
02641 }
02642 else
02643 write_string(node->value.text.string);
02644 }
02645 }
02646
02647
02648
02649
02650
02651
02652 static void
02653 write_string(const char *s)
02654 {
02655 while (*s)
02656 {
02657 if (*s == '&')
02658 fputs("&", stdout);
02659 else if (*s == '<')
02660 fputs("<", stdout);
02661 else if (*s == '>')
02662 fputs(">", stdout);
02663 else if (*s == '\"')
02664 fputs(""", stdout);
02665 else if (*s & 128)
02666 {
02667
02668
02669
02670
02671 int ch;
02672
02673
02674 ch = *s & 255;
02675
02676 if ((ch & 0xe0) == 0xc0)
02677 {
02678 ch = ((ch & 0x1f) << 6) | (s[1] & 0x3f);
02679 s ++;
02680 }
02681 else if ((ch & 0xf0) == 0xe0)
02682 {
02683 ch = ((((ch * 0x0f) << 6) | (s[1] & 0x3f)) << 6) | (s[2] & 0x3f);
02684 s += 2;
02685 }
02686
02687 if (ch == 0xa0)
02688 {
02689
02690
02691
02692
02693 fputs(" ", stdout);
02694 }
02695 else
02696 printf("&#x%x;", ch);
02697 }
02698 else
02699 putchar(*s);
02700
02701 s ++;
02702 }
02703 }
02704
02705
02706
02707
02708
02709
02710 static const char *
02711 ws_cb(mxml_node_t *node,
02712 int where)
02713 {
02714 const char *name;
02715 int depth;
02716 static const char *spaces = " ";
02717
02718
02719
02720 name = node->value.element.name;
02721
02722 switch (where)
02723 {
02724 case MXML_WS_BEFORE_CLOSE :
02725 if (strcmp(name, "argument") &&
02726 strcmp(name, "class") &&
02727 strcmp(name, "constant") &&
02728 strcmp(name, "enumeration") &&
02729 strcmp(name, "function") &&
02730 strcmp(name, "mxmldoc") &&
02731 strcmp(name, "namespace") &&
02732 strcmp(name, "returnvalue") &&
02733 strcmp(name, "struct") &&
02734 strcmp(name, "typedef") &&
02735 strcmp(name, "union") &&
02736 strcmp(name, "variable"))
02737 return (NULL);
02738
02739 for (depth = -4; node; node = node->parent, depth += 2);
02740 if (depth > 40)
02741 return (spaces);
02742 else if (depth < 2)
02743 return (NULL);
02744 else
02745 return (spaces + 40 - depth);
02746
02747 case MXML_WS_AFTER_CLOSE :
02748 return ("\n");
02749
02750 case MXML_WS_BEFORE_OPEN :
02751 for (depth = -4; node; node = node->parent, depth += 2);
02752 if (depth > 40)
02753 return (spaces);
02754 else if (depth < 2)
02755 return (NULL);
02756 else
02757 return (spaces + 40 - depth);
02758
02759 default :
02760 case MXML_WS_AFTER_OPEN :
02761 if (strcmp(name, "argument") &&
02762 strcmp(name, "class") &&
02763 strcmp(name, "constant") &&
02764 strcmp(name, "enumeration") &&
02765 strcmp(name, "function") &&
02766 strcmp(name, "mxmldoc") &&
02767 strcmp(name, "namespace") &&
02768 strcmp(name, "returnvalue") &&
02769 strcmp(name, "struct") &&
02770 strcmp(name, "typedef") &&
02771 strcmp(name, "union") &&
02772 strcmp(name, "variable"))
02773 return (NULL);
02774 else
02775 return ("\n");
02776 }
02777 }
02778
02779
02780
02781
02782