/*#define DEBUG 1*/
/*
* "$Id: mxmldoc.c 390 2009-05-05 13:38:00Z mike $"
*
* Documentation generator using Mini-XML, a small XML-like file parsing
* library.
*
* Copyright 2003-2009 by Michael Sweet.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Contents:
*
* main() - Main entry for test program.
* add_variable() - Add a variable or argument.
* find_public() - Find a public function, type, etc.
* get_comment_info() - Get info from comment.
* get_text() - Get the text for a node.
* load_cb() - Set the type of child nodes.
* new_documentation() - Create a new documentation tree.
* remove_directory() - Remove a directory.
* safe_strcpy() - Copy a string allowing for overlapping strings.
* scan_file() - Scan a source file.
* sort_node() - Insert a node sorted into a tree.
* update_comment() - Update a comment node.
* usage() - Show program usage...
* write_description() - Write the description text.
* write_element() - Write an element's text nodes.
* write_file() - Copy a file to the output.
* write_function() - Write documentation for a function.
* write_html() - Write HTML documentation.
* write_html_head() - Write the standard HTML header.
* write_man() - Write manpage documentation.
* write_scu() - Write a structure, class, or union.
* write_string() - Write a string, quoting HTML special chars as needed.
* write_toc() - Write a table-of-contents.
* write_tokens() - Write <Token> nodes for all APIs.
* ws_cb() - Whitespace callback for saving.
*/
/*
* Include necessary headers...
*/
#include "config.h"
#include "mxml.h"
#include <time.h>
#include <sys/stat.h>
#ifndef WIN32
# include <dirent.h>
# include <unistd.h>
# include <spawn.h>
# include <sys/wait.h>
extern char **environ;
#endif /* !WIN32 */
/*
* This program scans source and header files and produces public API
* documentation for code that conforms to the CUPS Configuration
* Management Plan (CMP) coding standards. Please see the following web
* page for details:
*
* http://www.cups.org/cmp.html
*
* Using Mini-XML, this program creates and maintains an XML representation
* of the public API code documentation which can then be converted to HTML
* as desired. The following is a poor-man's schema:
*
* <?xml version="1.0"?>
* <mxmldoc xmlns="http://www.easysw.com"
* xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
* xsi:schemaLocation="http://www.minixml.org/mxmldoc.xsd">
*
* <namespace name=""> [optional...]
* <constant name="">
* <description>descriptive text</description>
* </constant>
*
* <enumeration name="">
* <description>descriptive text</description>
* <constant name="">...</constant>
* </enumeration>
*
* <typedef name="">
* <description>descriptive text</description>
* <type>type string</type>
* </typedef>
*
* <function name="" scope="">
* <description>descriptive text</description>
* <argument name="" direction="I|O|IO" default="">
* <description>descriptive text</description>
* <type>type string</type>
* </argument>
* <returnvalue>
* <description>descriptive text</description>
* <type>type string</type>
* </returnvalue>
* <seealso>function names separated by spaces</seealso>
* </function>
*
* <variable name="" scope="">
* <description>descriptive text</description>
* <type>type string</type>
* </variable>
*
* <struct name="">
* <description>descriptive text</description>
* <variable name="">...</variable>
* <function name="">...</function>
* </struct>
*
* <union name="">
* <description>descriptive text</description>
* <variable name="">...</variable>
* </union>
*
* <class name="" parent="">
* <description>descriptive text</description>
* <class name="">...</class>
* <enumeration name="">...</enumeration>
* <function name="">...</function>
* <struct name="">...</struct>
* <variable name="">...</variable>
* </class>
* </namespace>
* </mxmldoc>
*/
/*
* Basic states for file parser...
*/
#define STATE_NONE 0 /* No state - whitespace, etc. */
#define STATE_PREPROCESSOR 1 /* Preprocessor directive */
#define STATE_C_COMMENT 2 /* Inside a C comment */
#define STATE_CXX_COMMENT 3 /* Inside a C++ comment */
#define STATE_STRING 4 /* Inside a string constant */
#define STATE_CHARACTER 5 /* Inside a character constant */
#define STATE_IDENTIFIER 6 /* Inside a keyword/identifier */
/*
* Output modes...
*/
#define OUTPUT_NONE 0 /* No output */
#define OUTPUT_HTML 1 /* Output HTML */
#define OUTPUT_XML 2 /* Output XML */
#define OUTPUT_MAN 3 /* Output nroff/man */
#define OUTPUT_TOKENS 4 /* Output docset Tokens.xml file */
/*
* Local functions...
*/
static mxml_node_t *add_variable(mxml_node_t *parent, const char *name,
mxml_node_t *type);
static mxml_node_t *find_public(mxml_node_t *node, mxml_node_t *top,
const char *name);
static char *get_comment_info(mxml_node_t *description);
static char *get_text(mxml_node_t *node, char *buffer, int buflen);
static mxml_type_t load_cb(mxml_node_t *node);
static mxml_node_t *new_documentation(mxml_node_t **mxmldoc);
static int remove_directory(const char *path);
static void safe_strcpy(char *dst, const char *src);
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 void usage(const char *option);
static void write_description(FILE *out, mxml_node_t *description,
const char *element, int summary);
static void write_element(FILE *out, mxml_node_t *doc,
mxml_node_t *element, int mode);
static void write_file(FILE *out, const char *file);
static void write_function(FILE *out, mxml_node_t *doc,
mxml_node_t *function, int level);
static void write_html(const char *section, const char *title,
const char *footerfile,
const char *headerfile,
const char *introfile, const char *cssfile,
const char *framefile,
const char *docset, const char *docversion,
const char *feedname, const char *feedurl,
mxml_node_t *doc);
static void write_html_head(FILE *out, const char *section,
const char *title, const char *cssfile);
static void write_man(const char *man_name, const char *section,
const char *title, const char *headerfile,
const char *footerfile, const char *introfile,
mxml_node_t *doc);
static void write_scu(FILE *out, mxml_node_t *doc,
mxml_node_t *scut);
static void write_string(FILE *out, const char *s, int mode);
static void write_toc(FILE *out, mxml_node_t *doc,
const char *introfile, const char *target,
int xml);
static void write_tokens(FILE *out, mxml_node_t *doc,
const char *path);
static const char *ws_cb(mxml_node_t *node, int where);
/*
* 'main()' - Main entry for test program.
*/
int /* O - Exit status */
main(int argc, /* I - Num