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