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