mirror of
https://github.com/michaelrsweet/mxml.git
synced 2024-11-24 11:25:30 +00:00
Working mxmldoc core.
This commit is contained in:
parent
1d1c545e64
commit
a9403b21b4
3
CHANGES
3
CHANGES
@ -4,6 +4,9 @@ README - 06/04/2003
|
||||
|
||||
CHANGES IN Mini-XML 0.93
|
||||
|
||||
- New mxmldoc example program that is used to track code
|
||||
documentation using XML and produce HTML reference
|
||||
pages.
|
||||
- Added mxmlAdd() and mxmlRemove() functions to add and
|
||||
remove nodes from a tree. This provides more
|
||||
flexibility over where the nodes are inserted and
|
||||
|
15
mxml-node.c
15
mxml-node.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* "$Id: mxml-node.c,v 1.3 2003/06/04 21:19:00 mike Exp $"
|
||||
* "$Id: mxml-node.c,v 1.4 2003/06/05 03:06:20 mike Exp $"
|
||||
*
|
||||
* Node support code for mini-XML, a small XML-like file parsing library.
|
||||
*
|
||||
@ -52,6 +52,9 @@ mxmlAdd(mxml_node_t *parent, /* I - Parent node */
|
||||
mxml_node_t *child, /* I - Child node for where */
|
||||
mxml_node_t *node) /* I - Node to add */
|
||||
{
|
||||
/* fprintf(stderr, "mxmlAdd(parent=%p, where=%d, child=%p, node=%p)\n", parent,
|
||||
where, child, node);*/
|
||||
|
||||
/*
|
||||
* Range check input...
|
||||
*/
|
||||
@ -156,6 +159,8 @@ mxmlDelete(mxml_node_t *node) /* I - Node */
|
||||
int i; /* Looping var */
|
||||
|
||||
|
||||
/* fprintf(stderr, "mxmlDelete(node=%p)\n", node);*/
|
||||
|
||||
/*
|
||||
* Range check input...
|
||||
*/
|
||||
@ -383,6 +388,8 @@ mxmlRemove(mxml_node_t *node) /* I - Node to remove */
|
||||
* Range check input...
|
||||
*/
|
||||
|
||||
/* fprintf(stderr, "mxmlRemove(node=%p)\n", node);*/
|
||||
|
||||
if (!node || !node->parent)
|
||||
return;
|
||||
|
||||
@ -399,6 +406,10 @@ mxmlRemove(mxml_node_t *node) /* I - Node to remove */
|
||||
node->next->prev = node->prev;
|
||||
else
|
||||
node->parent->last_child = node->prev;
|
||||
|
||||
node->parent = NULL;
|
||||
node->prev = NULL;
|
||||
node->next = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -442,5 +453,5 @@ mxml_new(mxml_node_t *parent, /* I - Parent node */
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: mxml-node.c,v 1.3 2003/06/04 21:19:00 mike Exp $".
|
||||
* End of "$Id: mxml-node.c,v 1.4 2003/06/05 03:06:20 mike Exp $".
|
||||
*/
|
||||
|
219
mxmldoc.c
219
mxmldoc.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* "$Id: mxmldoc.c,v 1.5 2003/06/04 23:20:31 mike Exp $"
|
||||
* "$Id: mxmldoc.c,v 1.6 2003/06/05 03:06:20 mike Exp $"
|
||||
*
|
||||
* Documentation generator using mini-XML, a small XML-like file parsing
|
||||
* library.
|
||||
@ -96,6 +96,8 @@
|
||||
static int scan_file(const char *filename, FILE *fp,
|
||||
mxml_node_t *doc);
|
||||
static void sort_node(mxml_node_t *tree, mxml_node_t *func);
|
||||
static void update_comment(mxml_node_t *parent,
|
||||
mxml_node_t *comment);
|
||||
static int ws_cb(mxml_node_t *node, int where);
|
||||
|
||||
|
||||
@ -236,8 +238,6 @@ scan_file(const char *filename, /* I - Filename */
|
||||
mxml_node_t *tree) /* I - Function tree */
|
||||
{
|
||||
int state, /* Current parser state */
|
||||
oldstate, /* Previous state */
|
||||
oldch, /* Old character */
|
||||
braces, /* Number of braces active */
|
||||
parens; /* Number of active parenthesis */
|
||||
int ch;
|
||||
@ -245,11 +245,15 @@ scan_file(const char *filename, /* I - Filename */
|
||||
*bufptr;
|
||||
mxml_node_t *comment, /* <comment> node */
|
||||
*function, /* <function> node */
|
||||
*structure, /* <struct> or <class> node */
|
||||
*variable, /* <variable> or <argument> node */
|
||||
*returnvalue, /* <returnvalue> node */
|
||||
*type, /* <type> node */
|
||||
*description; /* <description> node */
|
||||
static const char *states[] =
|
||||
#ifdef DEBUG
|
||||
int oldstate, /* Previous state */
|
||||
oldch; /* Old character */
|
||||
static const char *states[] = /* State strings */
|
||||
{
|
||||
"STATE_NONE",
|
||||
"STATE_PREPROCESSOR",
|
||||
@ -259,6 +263,7 @@ scan_file(const char *filename, /* I - Filename */
|
||||
"STATE_CHARACTER",
|
||||
"STATE_IDENTIFIER"
|
||||
};
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
||||
/*
|
||||
@ -270,7 +275,8 @@ scan_file(const char *filename, /* I - Filename */
|
||||
parens = 0;
|
||||
bufptr = buffer;
|
||||
|
||||
comment = NULL;
|
||||
comment = mxmlNewElement(MXML_NO_PARENT, "temp");
|
||||
structure = NULL;
|
||||
function = NULL;
|
||||
variable = NULL;
|
||||
returnvalue = NULL;
|
||||
@ -283,8 +289,10 @@ scan_file(const char *filename, /* I - Filename */
|
||||
|
||||
while ((ch = getc(fp)) != EOF)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
oldstate = state;
|
||||
oldch = ch;
|
||||
#endif /* DEBUG */
|
||||
|
||||
switch (state)
|
||||
{
|
||||
@ -335,6 +343,21 @@ scan_file(const char *filename, /* I - Filename */
|
||||
parens --;
|
||||
break;
|
||||
|
||||
case ';' :
|
||||
function = NULL;
|
||||
variable = NULL;
|
||||
break;
|
||||
|
||||
case '*' :
|
||||
if (type)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fputs("Identifier: <<< * >>>\n", stderr);
|
||||
#endif /* DEBUG */
|
||||
mxmlNewText(type, 1, "*");
|
||||
}
|
||||
break;
|
||||
|
||||
default : /* Other */
|
||||
if (isalpha(ch) || ch == '_')
|
||||
{
|
||||
@ -342,13 +365,6 @@ scan_file(const char *filename, /* I - Filename */
|
||||
bufptr = buffer;
|
||||
*bufptr++ = ch;
|
||||
}
|
||||
else if (ch == '*')
|
||||
{
|
||||
puts("Identifier: <<< * >>>");
|
||||
|
||||
if (type)
|
||||
mxmlNewText(type, 1, "*");
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -373,21 +389,21 @@ scan_file(const char *filename, /* I - Filename */
|
||||
{
|
||||
*bufptr = '\0';
|
||||
|
||||
if (comment)
|
||||
{
|
||||
mxmlDelete(comment);
|
||||
comment = NULL;
|
||||
}
|
||||
if (comment->child != comment->last_child)
|
||||
mxmlDelete(comment->child);
|
||||
|
||||
if (variable)
|
||||
{
|
||||
description = mxmlNewElement(variable, "description");
|
||||
mxmlNewText(description, 0, buffer);
|
||||
update_comment(variable,
|
||||
mxmlNewText(description, 0, buffer));
|
||||
}
|
||||
else
|
||||
comment = mxmlNewText(MXML_NO_PARENT, 0, buffer);
|
||||
mxmlNewText(comment, 0, buffer);
|
||||
|
||||
printf("C comment: <<< %s >>>\n", buffer);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "C comment: <<< %s >>>\n", buffer);
|
||||
#endif /* DEBUG */
|
||||
|
||||
state = STATE_NONE;
|
||||
break;
|
||||
@ -404,7 +420,7 @@ scan_file(const char *filename, /* I - Filename */
|
||||
if (ch != EOF)
|
||||
ungetc(ch, fp);
|
||||
|
||||
if (bufptr < (buffer + sizeof(buffer) - 1))
|
||||
if (bufptr > buffer && bufptr < (buffer + sizeof(buffer) - 1))
|
||||
*bufptr++ = '\n';
|
||||
break;
|
||||
|
||||
@ -416,21 +432,21 @@ scan_file(const char *filename, /* I - Filename */
|
||||
bufptr --;
|
||||
*bufptr = '\0';
|
||||
|
||||
if (comment)
|
||||
{
|
||||
mxmlDelete(comment);
|
||||
comment = NULL;
|
||||
}
|
||||
if (comment->child != comment->last_child)
|
||||
mxmlDelete(comment->child);
|
||||
|
||||
if (variable)
|
||||
{
|
||||
description = mxmlNewElement(variable, "description");
|
||||
mxmlNewText(description, 0, buffer);
|
||||
update_comment(variable,
|
||||
mxmlNewText(description, 0, buffer));
|
||||
}
|
||||
else
|
||||
comment = mxmlNewText(MXML_NO_PARENT, 0, buffer);
|
||||
mxmlNewText(comment, 0, buffer);
|
||||
|
||||
printf("C comment: <<< %s >>>\n", buffer);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "C comment: <<< %s >>>\n", buffer);
|
||||
#endif /* DEBUG */
|
||||
|
||||
state = STATE_NONE;
|
||||
break;
|
||||
@ -451,21 +467,21 @@ scan_file(const char *filename, /* I - Filename */
|
||||
{
|
||||
*bufptr = '\0';
|
||||
|
||||
if (comment)
|
||||
{
|
||||
mxmlDelete(comment);
|
||||
comment = NULL;
|
||||
}
|
||||
if (comment->child != comment->last_child)
|
||||
mxmlDelete(comment->child);
|
||||
|
||||
if (variable)
|
||||
{
|
||||
description = mxmlNewElement(variable, "description");
|
||||
mxmlNewText(description, 0, buffer);
|
||||
update_comment(variable,
|
||||
mxmlNewText(description, 0, buffer));
|
||||
}
|
||||
else
|
||||
comment = mxmlNewText(MXML_NO_PARENT, 0, buffer);
|
||||
mxmlNewText(comment, 0, buffer);
|
||||
|
||||
printf("C++ comment: <<< %s >>>\n", buffer);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "C++ comment: <<< %s >>>\n", buffer);*/
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
else if (ch == ' ' && bufptr == buffer)
|
||||
break;
|
||||
@ -497,7 +513,7 @@ scan_file(const char *filename, /* I - Filename */
|
||||
{
|
||||
ungetc(ch, fp);
|
||||
*bufptr = '\0';
|
||||
printf("Identifier: <<< %s >>>\n", buffer);
|
||||
state = STATE_NONE;
|
||||
|
||||
if (!braces)
|
||||
{
|
||||
@ -506,18 +522,34 @@ scan_file(const char *filename, /* I - Filename */
|
||||
|
||||
if (!function && ch == '(')
|
||||
{
|
||||
if (type->child &&
|
||||
!strcmp(type->child->value.text.string, "extern"))
|
||||
{
|
||||
mxmlDelete(type);
|
||||
type = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
function = mxmlNewElement(MXML_NO_PARENT, "function");
|
||||
mxmlElementSetAttr(function, "name", buffer);
|
||||
|
||||
sort_node(tree, function);
|
||||
|
||||
description = mxmlNewElement(function, "description");
|
||||
update_comment(function, comment->child);
|
||||
mxmlAdd(description, MXML_ADD_AFTER, MXML_ADD_TO_PARENT,
|
||||
comment->child);
|
||||
|
||||
returnvalue = mxmlNewElement(function, "returnvalue");
|
||||
|
||||
mxmlAdd(returnvalue, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, comment);
|
||||
description = mxmlNewElement(returnvalue, "description");
|
||||
update_comment(returnvalue, comment->child);
|
||||
mxmlAdd(description, MXML_ADD_AFTER, MXML_ADD_TO_PARENT,
|
||||
comment->child);
|
||||
|
||||
mxmlAdd(returnvalue, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, type);
|
||||
|
||||
comment = NULL;
|
||||
type = NULL;
|
||||
type = NULL;
|
||||
}
|
||||
else if (function && (ch == ')' || ch == ','))
|
||||
{
|
||||
@ -553,19 +585,19 @@ scan_file(const char *filename, /* I - Filename */
|
||||
mxmlDelete(type);
|
||||
type = NULL;
|
||||
}
|
||||
|
||||
state = STATE_NONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#ifdef DEBUG
|
||||
if (state != oldstate)
|
||||
printf("changed states from %s to %s on receipt of character '%c'...\n",
|
||||
states[oldstate], states[state], oldch);
|
||||
#endif /* 0 */
|
||||
fprintf(stderr, "changed states from %s to %s on receipt of character '%c'...\n",
|
||||
states[oldstate], states[state], oldch);
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
|
||||
mxmlDelete(comment);
|
||||
|
||||
/*
|
||||
* All done, return with no errors...
|
||||
*/
|
||||
@ -610,11 +642,89 @@ sort_node(mxml_node_t *tree, /* I - Tree to sort into */
|
||||
if ((tempname = mxmlElementGetAttr(temp, "name")) == NULL)
|
||||
continue;
|
||||
|
||||
if (strcmp(nodename, tempname) > 0)
|
||||
if (strcmp(nodename, tempname) < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
mxmlAdd(tree, MXML_ADD_AFTER, temp, node);
|
||||
if (temp)
|
||||
mxmlAdd(tree, MXML_ADD_BEFORE, temp, node);
|
||||
else
|
||||
mxmlAdd(tree, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, node);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'update_comment()' - Update a comment node.
|
||||
*/
|
||||
|
||||
static void /* Returns nothing */
|
||||
update_comment(mxml_node_t *parent, /* I - Parent node */
|
||||
mxml_node_t *comment) /* I - Comment node */
|
||||
{
|
||||
char *ptr; /* Pointer into comment */
|
||||
|
||||
|
||||
/*
|
||||
* Range check the input...
|
||||
*/
|
||||
|
||||
if (!parent || !comment)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Update the comment...
|
||||
*/
|
||||
|
||||
ptr = comment->value.text.string;
|
||||
|
||||
if (*ptr == '\'')
|
||||
{
|
||||
/*
|
||||
* Convert "'name()' - description" to "description".
|
||||
*/
|
||||
|
||||
for (ptr ++; *ptr && *ptr != '\''; ptr ++);
|
||||
|
||||
if (*ptr == '\'')
|
||||
{
|
||||
ptr ++;
|
||||
while (isspace(*ptr))
|
||||
ptr ++;
|
||||
|
||||
if (*ptr == '-')
|
||||
ptr ++;
|
||||
|
||||
while (isspace(*ptr))
|
||||
ptr ++;
|
||||
|
||||
strcpy(comment->value.text.string, ptr);
|
||||
}
|
||||
}
|
||||
else if (!strncmp(ptr, "I ", 2) || !strncmp(ptr, "O ", 2) ||
|
||||
!strncmp(ptr, "IO ", 3))
|
||||
{
|
||||
/*
|
||||
* 'Convert "I - description", "IO - description", or "O - description"
|
||||
* to description + directory attribute.
|
||||
*/
|
||||
|
||||
ptr = strchr(ptr, ' ');
|
||||
*ptr++ = '\0';
|
||||
|
||||
if (!strcmp(parent->value.element.name, "argument"))
|
||||
mxmlElementSetAttr(parent, "direction", comment->value.text.string);
|
||||
|
||||
while (isspace(*ptr))
|
||||
ptr ++;
|
||||
|
||||
if (*ptr == '-')
|
||||
ptr ++;
|
||||
|
||||
while (isspace(*ptr))
|
||||
ptr ++;
|
||||
|
||||
strcpy(comment->value.text.string, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -634,13 +744,8 @@ ws_cb(mxml_node_t *node, /* I - Element node */
|
||||
if (!strcmp(name, "namespace") || !strcmp(name, "enumeration") ||
|
||||
!strcmp(name, "typedef") || !strcmp(name, "function") ||
|
||||
!strcmp(name, "variable") || !strcmp(name, "struct") ||
|
||||
!strcmp(name, "class"))
|
||||
{
|
||||
if (where < MXML_WS_AFTER_OPEN)
|
||||
return ('\n');
|
||||
}
|
||||
else if (!strcmp(name, "constant") || !strcmp(name, "argument") ||
|
||||
!strcmp(name, "returnvalue"))
|
||||
!strcmp(name, "class") || !strcmp(name, "constant") ||
|
||||
!strcmp(name, "argument") || !strcmp(name, "returnvalue"))
|
||||
{
|
||||
if (where <= MXML_WS_AFTER_OPEN)
|
||||
return ('\n');
|
||||
@ -655,5 +760,5 @@ ws_cb(mxml_node_t *node, /* I - Element node */
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: mxmldoc.c,v 1.5 2003/06/04 23:20:31 mike Exp $".
|
||||
* End of "$Id: mxmldoc.c,v 1.6 2003/06/05 03:06:20 mike Exp $".
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user