diff --git a/CHANGES b/CHANGES index 72c5a06..2456a17 100644 --- a/CHANGES +++ b/CHANGES @@ -1,11 +1,12 @@ -README - 06/05/2003 +README - 06/07/2003 ------------------- CHANGES IN Mini-XML 0.94 - - The mxmldoc program now handles function arguments - properly. + - The mxmldoc program now handles function arguments, + structures, unions, enumerations, classes, and + typedefs properly. Finally some documentation... CHANGES IN Mini-XML 0.93 diff --git a/documentation.html b/documentation.html index d23803d..9142a11 100644 --- a/documentation.html +++ b/documentation.html @@ -9,7 +9,36 @@ --> -

Functions

+

Contents

+ +

Classes

+ +

Enumerations

+ +
+

mxml_type_e

+

Node Type

+

Values

+

+ + + + + + + +
NameDescription
MXML_ELEMENTXML element with attributes
MXML_INTEGERInteger value
MXML_OPAQUEOpaque string
MXML_REALReal value
MXML_TEXTText fragment

+

Functions


mxmlAdd()

-

Add a node to a tree.

+

Local functions...

Syntax

 void
@@ -136,7 +165,7 @@ mxmlFindElement(
 

Element node or NULL


mxmlLoadFile()

-

Load a file into an XML node tree.

+

mxml_node_t *Top nodeFILE *File to read frommxml_type_tCallback functionNew nodemxml_node_t *Create a new element node.mxml_node_t *Parent nodeconst char *Name of elementNew nodemxml_node_t *Create a new integer node.mxml_node_t *Parent nodeintInteger valueNew nodemxml_node_t *Create a new opaque string.mxml_node_t *Parent nodeconst char *Opaque stringNew nodemxml_node_t *Create a new real number node.mxml_node_t *Parent nodedoubleReal number valueNew nodemxml_node_t *Create a new text fragment node.mxml_node_t *Parent nodeintLeading whitespace?const char *StringRemove a node from its parent.mxml_node_t *Node to remove0 on success, -1 on errorintSave an XML tree to a file.mxml_node_t *Node to writeFILE *File to write tointWhitespace callbackNext node or NULLmxml_node_t *Walk to the next logical node in the tree.mxml_node_t *Current nodemxml_node_t *Top nodeintDescend into tree?Previous node or NULLmxml_node_t *Walk to the previous logical node in the tree.mxml_node_t *Current nodemxml_node_t *Top nodeintDescend into tree?Data types...char *Attribute namechar *Attribute valuestruct mxml_attr_sstruct mxml_value_smxml_node_t *First child nodemxml_node_t *Last child nodemxml_node_t *Next node under same parentmxml_node_t *Parent nodemxml_node_t *Previous node under same parentmxml_type_tNode typemxml_value_tNode valuechar *Fragment stringintLeading whitespace?struct mxml_text_sNode TypeXML element with attributesInteger valueOpaque stringReal valueText fragmentAttribute ValueElement ValueText ValueNode ValueNodeC++ support...Prototypes...C++ support...End of "$Id: documentation.html,v 1.3 2003/06/07 21:27:05 mike Exp $".enum mxml_type_emxml_attr_t *Attributeschar *Name of elementintNumber of attributesunion mxml_value_umxml_element_tElementintInteger numberchar *Opaque stringdoubleReal numbermxml_text_tText fragmentmxml_node_t *Current nodemxml_node_t *Parent nodeNode typeconst char *String to writeFile to write toint(*cb)(mxml_node_t *int) intWhere valueCurrent column

Syntax

 mxml_node_t *
@@ -154,7 +183,7 @@ mxmlLoadFile(
 (*cb)(mxml_node_t *)Callback function
 

Returns

-

First node

+

Local functions...


mxmlNewElement()

Create a new element node.

@@ -332,5 +361,162 @@ mxmlWalkPrev(

Returns

Previous node or NULL

+

Structures

+ +
+

mxml_attr_s

+

Data types...

+

Definition

+
+struct mxml_attr_s
+{
+  char * name;
+  char * value;
+};
+
+

Members

+

+ + + + +
NameDescription
nameAttribute name
valueAttribute value

+
+

mxml_node_s

+

mxml_node_t *First child nodemxml_node_t *Last child nodemxml_node_t *Next node under same parentmxml_node_t *Parent nodemxml_node_t *Previous node under same parentmxml_type_tNode typemxml_value_tNode valuechar *Fragment stringintLeading whitespace?struct mxml_text_sNode TypeXML element with attributesInteger valueOpaque stringReal valueText fragmentAttribute ValueElement ValueText ValueNode ValueNodeC++ support...Prototypes...C++ support...End of "$Id: documentation.html,v 1.3 2003/06/07 21:27:05 mike Exp $".enum mxml_type_emxml_attr_t *Attributeschar *Name of elementintNumber of attributesunion mxml_value_umxml_element_tElementintInteger numberchar *Opaque stringdoubleReal numbermxml_text_tText fragmentmxml_node_t *Current nodemxml_node_t *Parent nodeNode typeconst char *String to writeFile to write toint(*cb)(mxml_node_t *int) intWhere valueCurrent column

+

Definition

+
+struct mxml_node_s
+{
+  mxml_node_t * child;
+  mxml_node_t * last_child;
+  mxml_node_t * next;
+  mxml_node_t * parent;
+  mxml_node_t * prev;
+  mxml_type_t type;
+  mxml_value_t value;
+};
+
+

Members

+

+ + + + + + + + + +
NameDescription
childFirst child node
last_childLast child node
nextNext node under same parent
parentParent node
prevPrevious node under same parent
typeNode type
valueNode value

+
+

mxml_text_s

+

char *Fragment stringintLeading whitespace?struct mxml_text_sNode TypeXML element with attributesInteger valueOpaque stringReal valueText fragmentAttribute ValueElement ValueText ValueNode ValueNodeC++ support...Prototypes...C++ support...End of "$Id: documentation.html,v 1.3 2003/06/07 21:27:05 mike Exp $".enum mxml_type_emxml_attr_t *Attributeschar *Name of elementintNumber of attributesunion mxml_value_umxml_element_tElementintInteger numberchar *Opaque stringdoubleReal numbermxml_text_tText fragmentmxml_node_t *Current nodemxml_node_t *Parent nodeNode typeconst char *String to writeFile to write toint(*cb)(mxml_node_t *int) intWhere valueCurrent column

+

Definition

+
+struct mxml_text_s
+{
+  char * string;
+  int whitespace;
+};
+
+

Members

+

+ + + + +
NameDescription
stringFragment string
whitespaceLeading whitespace?

+
+

mxml_value_s

+

mxml_attr_t *Attributeschar *Name of elementintNumber of attributesunion mxml_value_umxml_element_tElementintInteger numberchar *Opaque stringdoubleReal numbermxml_text_tText fragmentmxml_node_t *Current nodemxml_node_t *Parent nodeNode typeconst char *String to writeFile to write toint(*cb)(mxml_node_t *int) intWhere valueCurrent column

+

Definition

+
+struct mxml_value_s
+{
+  mxml_attr_t * attrs;
+  char * name;
+  int num_attrs;
+};
+
+

Members

+

+ + + + + +
NameDescription
attrsAttributes
nameName of element
num_attrsNumber of attributes

+

Types

+ +
+

mxml_attr_t

+

Definition

+
+typedef struct mxml_attr_s mxml_attr_t;
+
+
+

mxml_element_t

+

Definition

+
+typedef struct mxml_value_s mxml_element_t;
+
+
+

mxml_text_t

+

Definition

+
+typedef struct mxml_text_s mxml_text_t;
+
+
+

mxml_type_t

+

Definition

+
+typedef enum mxml_type_e mxml_type_t;
+
+
+

mxml_value_t

+

Definition

+
+typedef union mxml_value_u mxml_value_t;
+
+

Unions

+ +
+

mxml_value_u

+

mxml_element_tElementintInteger numberchar *Opaque stringdoubleReal numbermxml_text_tText fragmentmxml_node_t *Current nodemxml_node_t *Parent nodeNode typeconst char *String to writeFile to write toint(*cb)(mxml_node_t *int) intWhere valueCurrent column

+

Definition

+
+struct mxml_value_u
+{
+  mxml_element_t element;
+  int integer;
+  char * opaque;
+  double real;
+  mxml_text_t text;
+};
+
+

Members

+

+ + + + + + + +
NameDescription
elementElement
integerInteger number
opaqueOpaque string
realReal number
textText fragment

diff --git a/index.html b/index.html index b7851c4..0517aa8 100644 --- a/index.html +++ b/index.html @@ -3,10 +3,10 @@ Mini-XML Home Page @@ -16,10 +16,11 @@ href="../index.html">Back to Home Page ]

Mini-XML Home Page

-

Current Release: v0.93 [ Download Source (.tar.gz 51k) | -View Change Log | -Rate/Make Comments ]

+

Current Release: v0.94
+[ Download Source (.tar.gz +51k) | Change Log | Documentation | Rate/Make Comments ]

Introduction

@@ -105,11 +106,14 @@ using Mini-XML.

#include <mxml.h>
-

Nodes are defined by the mxml_node_t structure; the -type member defines the node type (element, integer, -opaque, real, or text) which determines which value you want to -look at in the value union. New nodes can be created -using the Nodes are defined by the mxml_node_t +structure; the type member +defines the node type (element, integer, opaque, real, or text) +which determines which value you want to look at in the value +union. New nodes can be created using the mxmlNewElement(), mxmlNewInteger(), diff --git a/mxml.h b/mxml.h index ba7c762..d81a2c8 100644 --- a/mxml.h +++ b/mxml.h @@ -1,5 +1,5 @@ /* - * "$Id: mxml.h,v 1.7 2003/06/04 21:19:00 mike Exp $" + * "$Id: mxml.h,v 1.8 2003/06/07 21:27:05 mike Exp $" * * Header file for mini-XML, a small XML-like file parsing library. * @@ -62,7 +62,7 @@ * Data types... */ -typedef enum /**** Node Type ****/ +typedef enum mxml_type_e /**** Node Type ****/ { MXML_ELEMENT, /* XML element with attributes */ MXML_INTEGER, /* Integer value */ @@ -71,41 +71,45 @@ typedef enum /**** Node Type ****/ MXML_TEXT /* Text fragment */ } mxml_type_t; -typedef struct /**** Attribute Value ****/ +typedef struct mxml_attr_s /**** Attribute Value ****/ { - char *name, /* Attribute name */ - *value; /* Attribute value */ + char *name; /* Attribute name */ + char *value; /* Attribute value */ } mxml_attr_t; -typedef struct /**** Element Value ****/ +typedef struct mxml_value_s /**** Element Value ****/ { char *name; /* Name of element */ int num_attrs; /* Number of attributes */ mxml_attr_t *attrs; /* Attributes */ } mxml_element_t; -typedef struct mxml_node_str mxml_node_t; +typedef struct mxml_text_s /**** Text Value ****/ +{ + int whitespace; /* Leading whitespace? */ + char *string; /* Fragment string */ +} mxml_text_t; -struct mxml_node_str /**** Node ****/ +typedef union mxml_value_u /**** Node Value ****/ +{ + mxml_element_t element; /* Element */ + int integer; /* Integer number */ + char *opaque; /* Opaque string */ + double real; /* Real number */ + mxml_text_t text; /* Text fragment */ +} mxml_value_t; + +typedef struct mxml_node_s mxml_node_t; + +struct mxml_node_s /**** Node ****/ { mxml_type_t type; /* Node type */ - mxml_node_t *next, /* Next node under same parent */ - *prev, /* Previous node under same parent */ - *parent, /* Parent node */ - *child, /* First child node */ - *last_child; /* Last child node */ - union - { - mxml_element_t element; /* Element */ - int integer; /* Integer number */ - char *opaque; /* Opaque string */ - double real; /* Real number */ - struct - { - int whitespace; /* Leading whitespace? */ - char *string; /* Fragment string */ - } text; /* Text fragment */ - } value; /* Node value */ + mxml_node_t *next; /* Next node under same parent */ + mxml_node_t *prev; /* Previous node under same parent */ + mxml_node_t *parent; /* Parent node */ + mxml_node_t *child; /* First child node */ + mxml_node_t *last_child; /* Last child node */ + mxml_value_t value; /* Node value */ }; @@ -158,5 +162,5 @@ extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top, /* - * End of "$Id: mxml.h,v 1.7 2003/06/04 21:19:00 mike Exp $". + * End of "$Id: mxml.h,v 1.8 2003/06/07 21:27:05 mike Exp $". */ diff --git a/mxml.xml b/mxml.xml index 23a79d2..86e4970 100644 --- a/mxml.xml +++ b/mxml.xml @@ -1,6 +1,6 @@ FILE *File to write toCallback function -Add a node to a tree.Local functions...mxml_node_t *Parent node intWhere to add mxml_node_t *Child node for where @@ -30,10 +30,9 @@ direction="I">mxml_node_t *Current node< const char *Attribute value, or NULL for any intDescend into tree? -First nodemxml_node_t +Local functions...mxml_node_t * -Load a file into an XML node tree.mxml_node_t *Top node +mxml_node_t *Top node FILE *File to read from mxml_type_tCallback function @@ -91,11 +90,46 @@ name="node" direction="I">mxml_node_t *Current nodemxml_node_t *Top node intDescend into tree? - - -typedef struct mxml_node_str - -mxml_node_t *Current node +Data types...char *Attribute name +char *Attribute value + +struct mxml_attr_s +struct mxml_value_s +mxml_node_t +*First child node +mxml_node_t *Last child node +mxml_node_t *Next node under same parent +mxml_node_t *Parent node +mxml_node_t *Previous node under same parent +mxml_type_tNode type +mxml_value_tNode value + +char +*Fragment string +intLeading whitespace? + +struct mxml_text_s +Node TypeXML element with attributes +Integer value +Opaque string +Real value +Text fragmentAttribute ValueElement ValueText ValueNode ValueNodeC++ support...Prototypes...C++ support...End of "$Id: mxml.xml,v 1.3 2003/06/07 21:27:05 mike Exp $". + +enum mxml_type_e +mxml_attr_t +*Attributes +char *Name of element +intNumber of attributes + +union mxml_value_u +mxml_element_tElement +intInteger number +char *Opaque string +doubleReal number +mxml_text_tText fragment +mxml_node_t *Current node mxml_node_t *Parent nodeNode type const char *String to writeFile to write to int(*cb)(mxml_node_t *int) intWhere valueCurrent column diff --git a/mxmldoc.c b/mxmldoc.c index 39a3dd7..0e558b3 100644 --- a/mxmldoc.c +++ b/mxmldoc.c @@ -1,5 +1,5 @@ /* - * "$Id: mxmldoc.c,v 1.9 2003/06/06 03:09:31 mike Exp $" + * "$Id: mxmldoc.c,v 1.10 2003/06/07 21:27:05 mike Exp $" * * Documentation generator using mini-XML, a small XML-like file parsing * library. @@ -320,13 +320,17 @@ scan_file(const char *filename, /* I - Filename */ char buffer[16384], /* String buffer */ *bufptr; /* Pointer into buffer */ mxml_node_t *comment, /* node */ + *constant, /* node */ + *enumeration, /* node */ *function, /* node */ - *parent, /* or node */ + *structclass, /* or node */ + *typedefnode, /* node */ *variable, /* or node */ *returnvalue, /* node */ *type, /* node */ *description; /* node */ #if DEBUG > 1 + mxml_node_t *temp; /* Temporary node */ int oldstate, /* Previous state */ oldch; /* Old character */ static const char *states[] = /* State strings */ @@ -352,12 +356,15 @@ scan_file(const char *filename, /* I - Filename */ bufptr = buffer; comment = mxmlNewElement(MXML_NO_PARENT, "temp"); - parent = tree; + constant = NULL; + enumeration = NULL; function = NULL; variable = NULL; returnvalue = NULL; type = NULL; description = NULL; + typedefnode = NULL; + structclass = NULL; /* * Read until end-of-file... @@ -400,8 +407,131 @@ scan_file(const char *filename, /* I - Filename */ break; case '{' : +#ifdef DEBUG + fputs(" open brace...\n", stderr); +#endif /* DEBUG */ + if (function) - sort_node(parent, function); + sort_node(tree, function); + else if (type && type->child && + ((!strcmp(type->child->value.text.string, "typedef") && + type->child->next && + (!strcmp(type->child->next->value.text.string, "struct") || + !strcmp(type->child->next->value.text.string, "union") || + !strcmp(type->child->next->value.text.string, "class"))) || + !strcmp(type->child->value.text.string, "union") || + !strcmp(type->child->value.text.string, "struct") || + !strcmp(type->child->value.text.string, "class"))) + { + /* + * Start of a class or structure... + */ + + if (!strcmp(type->child->value.text.string, "typedef")) + { +#ifdef DEBUG + fputs(" starting typedef...\n", stderr); +#endif /* DEBUG */ + + typedefnode = mxmlNewElement(MXML_NO_PARENT, "typedef"); + mxmlDelete(type->child); + } + else + typedefnode = NULL; + + structclass = mxmlNewElement(MXML_NO_PARENT, + type->child->value.text.string); + +#ifdef DEBUG + fprintf(stderr, "%c%s: <<< %s >>>\n", + toupper(type->child->value.text.string[0]), + type->child->value.text.string + 1, + type->child->next ? + type->child->next->value.text.string : "(noname)"); +#endif /* DEBUG */ + + if (type->child->next) + { + mxmlElementSetAttr(structclass, "name", + type->child->next->value.text.string); + sort_node(tree, structclass); + } + + if (typedefnode && type->child) + type->child->value.text.whitespace = 0; + else + { + mxmlDelete(type); + type = NULL; + } + + description = mxmlNewElement(structclass, "description"); + update_comment(structclass, comment->last_child); + mxmlAdd(description, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, + comment->last_child); + + if (scan_file(filename, fp, structclass)) + return (-1); + +#ifdef DEBUG + fputs(" ended typedef...\n", stderr); +#endif /* DEBUG */ + break; + } + else if (type && type->child && type->child->next && + (!strcmp(type->child->value.text.string, "enum") || + (!strcmp(type->child->value.text.string, "typedef") && + !strcmp(type->child->next->value.text.string, "enum")))) + { + /* + * Enumeration type... + */ + + if (!strcmp(type->child->value.text.string, "typedef")) + { +#ifdef DEBUG + fputs(" starting typedef...\n", stderr); +#endif /* DEBUG */ + + typedefnode = mxmlNewElement(MXML_NO_PARENT, "typedef"); + mxmlDelete(type->child); + } + else + typedefnode = NULL; + + enumeration = mxmlNewElement(MXML_NO_PARENT, "enumeration"); + +#ifdef DEBUG + fprintf(stderr, "Enumeration: <<< %s >>>\n", + type->child->next ? + type->child->next->value.text.string : "(noname)"); +#endif /* DEBUG */ + + if (type->child->next) + { + mxmlElementSetAttr(enumeration, "name", + type->child->next->value.text.string); + sort_node(tree, enumeration); + } + + if (typedefnode && type->child) + type->child->value.text.whitespace = 0; + else + { + mxmlDelete(type); + type = NULL; + } + + description = mxmlNewElement(enumeration, "description"); + update_comment(enumeration, comment->last_child); + mxmlAdd(description, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, + comment->last_child); + } + else if (type) + { + mxmlDelete(type); + type = NULL; + } braces ++; function = NULL; @@ -409,8 +539,16 @@ scan_file(const char *filename, /* I - Filename */ break; case '}' : +#ifdef DEBUG + fputs(" close brace...\n", stderr); +#endif /* DEBUG */ + + enumeration = NULL; + if (braces > 0) braces --; + else + return (0); break; case '(' : @@ -446,10 +584,26 @@ scan_file(const char *filename, /* I - Filename */ case ';' : if (function) + { mxmlDelete(function); + function = NULL; + } - function = NULL; - variable = NULL; + if (type) + { + mxmlDelete(type); + type = NULL; + } + break; + + case ':' : + if (type) + { +#ifdef DEBUG + fputs("Identifier: <<< : >>>\n", stderr); +#endif /* DEBUG */ + mxmlNewText(type, 1, ":"); + } break; case '*' : @@ -503,6 +657,20 @@ scan_file(const char *filename, /* I - Filename */ update_comment(variable, mxmlNewText(description, 0, buffer)); } + else if (constant) + { + description = mxmlNewElement(constant, "description"); + update_comment(constant, + mxmlNewText(description, 0, buffer)); + } + else if (strcmp(tree->value.element.name, "?xml") && + !mxmlFindElement(tree, tree, "description", + NULL, NULL, MXML_DESCEND_FIRST)) + { + description = mxmlNewElement(tree, "description"); + update_comment(tree, + mxmlNewText(description, 0, buffer)); + } else mxmlNewText(comment, 0, buffer); @@ -546,6 +714,20 @@ scan_file(const char *filename, /* I - Filename */ update_comment(variable, mxmlNewText(description, 0, buffer)); } + else if (constant) + { + description = mxmlNewElement(constant, "description"); + update_comment(constant, + mxmlNewText(description, 0, buffer)); + } + else if (strcmp(tree->value.element.name, "?xml") && + !mxmlFindElement(tree, tree, "description", + NULL, NULL, MXML_DESCEND_FIRST)) + { + description = mxmlNewElement(tree, "description"); + update_comment(tree, + mxmlNewText(description, 0, buffer)); + } else mxmlNewText(comment, 0, buffer); @@ -581,6 +763,20 @@ scan_file(const char *filename, /* I - Filename */ update_comment(variable, mxmlNewText(description, 0, buffer)); } + else if (constant) + { + description = mxmlNewElement(constant, "description"); + update_comment(constant, + mxmlNewText(description, 0, buffer)); + } + else if (strcmp(tree->value.element.name, "?xml") && + !mxmlFindElement(tree, tree, "description", + NULL, NULL, MXML_DESCEND_FIRST)) + { + description = mxmlNewElement(tree, "description"); + update_comment(tree, + mxmlNewText(description, 0, buffer)); + } else mxmlNewText(comment, 0, buffer); @@ -609,7 +805,7 @@ scan_file(const char *filename, /* I - Filename */ break; case STATE_IDENTIFIER : /* Inside a keyword or identifier */ - if (isalnum(ch) || ch == '_' || ch == '[' || ch == ']') + if (isalnum(ch) || ch == '_' || ch == '[' || ch == ']' || ch == ':') { if (bufptr < (buffer + sizeof(buffer) - 1)) *bufptr++ = ch; @@ -620,20 +816,16 @@ scan_file(const char *filename, /* I - Filename */ *bufptr = '\0'; state = STATE_NONE; -#ifdef DEBUG - fprintf(stderr, "Identifier: <<< %s >>>\n", buffer); -#endif /* DEBUG */ - if (!braces) { if (!type) type = mxmlNewElement(MXML_NO_PARENT, "type"); #ifdef DEBUG - fprintf(stderr, "function=%p (%s), ch='%c', parens=%d\n", + fprintf(stderr, " function=%p (%s), type->child=%p, ch='%c', parens=%d\n", function, function ? mxmlElementGetAttr(function, "name") : "null", - ch, parens); + type->child, ch, parens); #endif /* DEBUG */ if (!function && ch == '(') @@ -652,7 +844,7 @@ scan_file(const char *filename, /* I - Filename */ if (type->child && !strcmp(type->child->value.text.string, "static") && - !strcmp(parent->value.element.name, "?xml")) + !strcmp(tree->value.element.name, "?xml")) { /* * Remove static functions... @@ -699,40 +891,94 @@ scan_file(const char *filename, /* I - Filename */ type->last_child->value.text.string[0] != '*', buffer); +#ifdef DEBUG + fprintf(stderr, "Argument: <<< %s >>>\n", buffer); +#endif /* DEBUG */ + variable = add_variable(function, "argument", type); type = NULL; } - else if (!function && (ch == ';' || ch == ',')) + else if (type->child && !function && (ch == ';' || ch == ',')) { - /* - * Variable definition... - */ +#ifdef DEBUG + fprintf(stderr, " got semicolon, typedefnode=%p, structclass=%p\n", + typedefnode, structclass); +#endif /* DEBUG */ - mxmlNewText(type, type->child != NULL && - type->last_child->value.text.string[0] != '(' && - type->last_child->value.text.string[0] != '*', - buffer); + if (typedefnode || structclass) + { +#ifdef DEBUG + fprintf(stderr, "Typedef/struct/class: <<< %s >>>>\n", buffer); +#endif /* DEBUG */ - variable = add_variable(MXML_NO_PARENT, "variable", type); - type = NULL; + if (typedefnode) + { + mxmlElementSetAttr(typedefnode, "name", buffer); - sort_node(parent, variable); + sort_node(tree, typedefnode); + } + + if (structclass && !mxmlElementGetAttr(structclass, "name")) + { + fprintf(stderr, "setting struct/class name to %s!\n", + type->last_child->value.text.string); + mxmlElementSetAttr(structclass, "name", buffer); + + sort_node(tree, structclass); + structclass = NULL; + } + + if (typedefnode) + mxmlAdd(typedefnode, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, + type); + else + mxmlDelete(type); + + type = NULL; + typedefnode = NULL; + } + else + { + /* + * Variable definition... + */ + + mxmlNewText(type, type->child != NULL && + type->last_child->value.text.string[0] != '(' && + type->last_child->value.text.string[0] != '*', + buffer); + +#ifdef DEBUG + fprintf(stderr, "Variable: <<< %s >>>>\n", buffer); +#endif /* DEBUG */ + + variable = add_variable(MXML_NO_PARENT, "variable", type); + type = NULL; + + sort_node(tree, variable); + } } - else if (ch == '{' && type->child && - (!strcmp(type->child->value.text.string, "class") || - !strcmp(type->child->value.text.string, "enum") || - !strcmp(type->child->value.text.string, "struct") || - !strcmp(type->child->value.text.string, "typedef"))) - { - /* Handle structure/class/enum/typedef... */ - mxmlDelete(type); - type = NULL; - } else + { +#ifdef DEBUG + fprintf(stderr, "Identifier: <<< %s >>>>\n", buffer); +#endif /* DEBUG */ + mxmlNewText(type, type->child != NULL && type->last_child->value.text.string[0] != '(' && type->last_child->value.text.string[0] != '*', buffer); + } + } + else if (enumeration) + { +#ifdef DEBUG + fprintf(stderr, "Constant: <<< %s >>>\n", buffer); +#endif /* DEBUG */ + + constant = mxmlNewElement(MXML_NO_PARENT, "constant"); + mxmlElementSetAttr(constant, "name", buffer); + sort_node(enumeration, constant); } else if (type) { @@ -745,8 +991,17 @@ scan_file(const char *filename, /* I - Filename */ #if DEBUG > 1 if (state != oldstate) - fprintf(stderr, "changed states from %s to %s on receipt of character '%c'...\n", + { + fprintf(stderr, " changed states from %s to %s on receipt of character '%c'...\n", states[oldstate], states[state], oldch); + if (type) + { + fputs(" type =", stderr); + for (temp = type->child; temp; temp = temp->next) + fprintf(stderr, " \"%s\"", temp->value.text.string); + fputs("\n", stderr); + } + } #endif /* DEBUG > 1 */ } @@ -886,6 +1141,22 @@ update_comment(mxml_node_t *parent, /* I - Parent node */ strcpy(comment->value.text.string, ptr); } + + /* + * Eliminate leading and trailing *'s... + */ + + for (ptr = comment->value.text.string; *ptr == '*'; ptr ++); + for (; isspace(*ptr); ptr ++); + if (ptr > comment->value.text.string) + strcpy(comment->value.text.string, ptr); + + for (ptr = comment->value.text.string + strlen(comment->value.text.string) - 1; + ptr > comment->value.text.string && *ptr == '*'; + ptr --) + *ptr = '\0'; + for (; ptr > comment->value.text.string && isspace(*ptr); ptr --) + *ptr = '\0'; } @@ -896,15 +1167,18 @@ update_comment(mxml_node_t *parent, /* I - Parent node */ static void write_documentation(mxml_node_t *doc) /* I - XML documentation */ { - mxml_node_t *node, /* Current node */ - *function, /* Current function */ + mxml_node_t *function, /* Current function */ + *scut, /* Struct/class/union/typedef */ *arg, /* Current argument */ - *description, /* Description of function/var */ - *type; /* Type of returnvalue/var */ + *description; /* Description of function/var */ const char *name; /* Name of function/type */ char prefix; /* Prefix character */ + /* + * Standard header... + */ + puts(""); puts(""); @@ -918,7 +1192,165 @@ write_documentation(mxml_node_t *doc) /* I - XML documentation */ puts(""); puts(""); - puts("

Functions

"); + + /* + * Table of contents... + */ + + puts("

Contents

"); + puts(""); + + /* + * List of classes... + */ + + puts("

Classes

"); + puts(""); + + for (scut = mxmlFindElement(doc, doc, "class", NULL, NULL, + MXML_DESCEND_FIRST); + scut; + scut = mxmlFindElement(scut, doc, "class", NULL, NULL, + MXML_NO_DESCEND)) + { + name = mxmlElementGetAttr(scut, "name"); + puts("
"); + printf("

%s

\n", name, name); + + description = mxmlFindElement(scut, scut, "description", NULL, + NULL, MXML_DESCEND_FIRST); + if (description) + { + fputs("

", stdout); + write_element(description); + puts("

"); + } + + puts("

Definition

"); + puts("
");
+
+    printf("struct %s\n{\n", name);
+    for (arg = mxmlFindElement(scut, scut, "variable", NULL, NULL,
+                               MXML_DESCEND_FIRST);
+	 arg;
+	 arg = mxmlFindElement(arg, scut, "variable", NULL, NULL,
+                               MXML_NO_DESCEND))
+    {
+      printf("  ");
+      write_element(mxmlFindElement(arg, arg, "type", NULL,
+                                    NULL, MXML_DESCEND_FIRST));
+      printf(" %s;\n", mxmlElementGetAttr(arg, "name"));
+    }
+
+    puts("};\n
"); + + puts("

Members

"); + + puts("

"); + puts(""); + puts(""); + + for (arg = mxmlFindElement(scut, scut, "variable", NULL, NULL, + MXML_DESCEND_FIRST); + arg; + arg = mxmlFindElement(arg, scut, "variable", NULL, NULL, + MXML_NO_DESCEND)) + { + printf(""); + } + + puts("
NameDescription
%s", mxmlElementGetAttr(arg, "name")); + + write_element(mxmlFindElement(arg, arg, "description", NULL, + NULL, MXML_DESCEND_FIRST)); + + puts("

"); + } + + /* + * List of enumerations... + */ + + puts("

Enumerations

"); + puts(""); + + for (scut = mxmlFindElement(doc, doc, "enumeration", NULL, NULL, + MXML_DESCEND_FIRST); + scut; + scut = mxmlFindElement(scut, doc, "enumeration", NULL, NULL, + MXML_NO_DESCEND)) + { + name = mxmlElementGetAttr(scut, "name"); + puts("
"); + printf("

%s

\n", name, name); + + description = mxmlFindElement(scut, scut, "description", NULL, + NULL, MXML_DESCEND_FIRST); + if (description) + { + fputs("

", stdout); + write_element(description); + puts("

"); + } + + puts("

Values

"); + + puts("

"); + puts(""); + puts(""); + + for (arg = mxmlFindElement(scut, scut, "constant", NULL, NULL, + MXML_DESCEND_FIRST); + arg; + arg = mxmlFindElement(arg, scut, "constant", NULL, NULL, + MXML_NO_DESCEND)) + { + printf(""); + } + + puts("
NameDescription
%s", mxmlElementGetAttr(arg, "name")); + + write_element(mxmlFindElement(arg, arg, "description", NULL, + NULL, MXML_DESCEND_FIRST)); + + puts("

"); + } + /* + * List of functions... + */ + + puts("

Functions

"); puts("