⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mxmldoc.c

📁 MINIXml 具有 解析、查找、生成、遍历 功能,一般不是太复杂的应用足够了。可贵的是全部实现是标准c,移植很容易。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * "$Id: mxmldoc.c 275 2007-04-27 00:49:03Z mike $" * * Documentation generator using Mini-XML, a small XML-like file parsing * library. * * Copyright 2003-2007 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. *   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. *   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 elements text nodes. *   write_html()          - Write HTML documentation. *   write_man()           - Write manpage documentation. *   write_string()        - Write a string, quoting XHTML special chars *                           as needed... *   ws_cb()               - Whitespace callback for saving. *//* * Include necessary headers... */#include "config.h"#include "mxml.h"#include <time.h>/* * 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.easysw.com/~mike/mxml/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_MAN		2	/* Output nroff/man *//* * 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 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(mxml_node_t *description, int mode);static void		write_element(mxml_node_t *doc, mxml_node_t *element,			              int mode);static void		write_html(const char *section,			           const char *title,			           const char *intro,			           mxml_node_t *doc);static void		write_man(const char *man_name,			          const char *section,			          const char *title,			          const char *intro,			          mxml_node_t *doc);static void		write_string(const char *s, int mode);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 - Number of command-line args */     char *argv[])			/* I - Command-line args */{  int		i;			/* Looping var */  int		len;			/* Length of argument */  FILE		*fp;			/* File to read */  mxml_node_t	*doc;			/* XML documentation tree */  mxml_node_t	*mxmldoc;		/* mxmldoc node */  const char	*section;		/* Section/keywords of documentation */  const char	*title;			/* Title of documentation */  const char	*introfile;		/* Introduction file */  const char	*xmlfile;		/* XML file */  const char	*name;			/* Name of manpage */  int		update;			/* Updated XML file */  int		mode;			/* Output mode */ /*  * Check arguments...  */  name      = NULL;  section   = NULL;  title     = NULL;  introfile = NULL;  xmlfile   = NULL;  update    = 0;  doc       = NULL;  mxmldoc   = NULL;  mode      = OUTPUT_HTML;  for (i = 1; i < argc; i ++)    if (!strcmp(argv[i], "--help"))    {     /*      * Show help...      */      usage(NULL);    }    else if (!strcmp(argv[i], "--intro") && !introfile)    {     /*      * Set intro file...      */      i ++;      if (i < argc)        introfile = argv[i];      else        usage(NULL);    }    else if (!strcmp(argv[i], "--man") && !name)    {     /*      * Output manpage...      */      i ++;      if (i < argc)      {        mode = OUTPUT_MAN;        name = argv[i];      }      else        usage(NULL);    }    else if (!strcmp(argv[i], "--no-output"))      mode = OUTPUT_NONE;    else if (!strcmp(argv[i], "--section") && !section)    {     /*      * Set section/keywords...      */      i ++;      if (i < argc)        section = argv[i];      else        usage(NULL);    }    else if (!strcmp(argv[i], "--title") && !title)    {     /*      * Set title...      */      i ++;      if (i < argc)        title = argv[i];      else        usage(NULL);    }    else if (argv[i][0] == '-')    {     /*      * Unknown/bad option...      */      usage(argv[i]);    }    else    {     /*      * Process XML or source file...      */      len = strlen(argv[i]);      if (len > 4 && !strcmp(argv[i] + len - 4, ".xml"))      {       /*        * Set XML file...	*/        if (xmlfile)	  usage(NULL);        xmlfile = argv[i];        if (!doc)	{	  if ((fp = fopen(argv[i], "r")) != NULL)	  {	   /*	    * Read the existing XML file...	    */	    doc = mxmlLoadFile(NULL, fp, load_cb);	    fclose(fp);	    if (!doc)	    {	      mxmldoc = NULL;	      fprintf(stderr, "mxmldoc: Unable to read the XML documentation file \"%s\"!\n",        	      argv[i]);	    }	    else if ((mxmldoc = mxmlFindElement(doc, doc, "mxmldoc", NULL,                                        	NULL, MXML_DESCEND)) == NULL)	    {	      fprintf(stderr, "mxmldoc: XML documentation file \"%s\" is missing <mxmldoc> node!!\n",        	      argv[i]);	      mxmlDelete(doc);	      doc = NULL;	    }	  }	  else	  {	    doc     = NULL;	    mxmldoc = NULL;	  }	  if (!doc)	    doc = new_documentation(&mxmldoc);        }      }      else      {       /*        * Load source file...	*/        update = 1;	if (!doc)	  doc = new_documentation(&mxmldoc);	if ((fp = fopen(argv[i], "r")) == NULL)	{	  fprintf(stderr, "mxmldoc: Unable to open source file \"%s\": %s\n",	          argv[i], strerror(errno));	  mxmlDelete(doc);	  return (1);	}	else if (scan_file(argv[i], fp, mxmldoc))	{	  fclose(fp);	  mxmlDelete(doc);	  return (1);	}	else	  fclose(fp);      }    }  if (update && xmlfile)  {   /*    * Save the updated XML documentation file...    */    if ((fp = fopen(xmlfile, "w")) != NULL)    {     /*      * Write over the existing XML file...      */      if (mxmlSaveFile(doc, fp, ws_cb))      {	fprintf(stderr, "mxmldoc: Unable to write the XML documentation file \"%s\": %s!\n",        	xmlfile, strerror(errno));	fclose(fp);	mxmlDelete(doc);	return (1);      }      fclose(fp);    }    else    {      fprintf(stderr, "mxmldoc: Unable to create the XML documentation file \"%s\": %s!\n",              xmlfile, strerror(errno));      mxmlDelete(doc);      return (1);    }  }  switch (mode)  {    case OUTPUT_HTML :       /*        * Write HTML documentation...        */        write_html(section, title ? title : "Documentation", introfile,                   mxmldoc);        break;    case OUTPUT_MAN :       /*        * Write manpage documentation...        */        write_man(name, section, title, introfile, mxmldoc);        break;  }   /*  * Delete the tree and return...  */  mxmlDelete(doc);  return (0);}/* * 'add_variable()' - Add a variable or argument. */static mxml_node_t *			/* O - New variable/argument */add_variable(mxml_node_t *parent,	/* I - Parent node */             const char  *name,		/* I - "argument" or "variable" */             mxml_node_t *type)		/* I - Type nodes */{  mxml_node_t	*variable,		/* New variable */		*node,			/* Current node */		*next;			/* Next node */  char		buffer[16384],		/* String buffer */		*bufptr;		/* Pointer into buffer */#ifdef DEBUG  fprintf(stderr, "add_variable(parent=%p, name=\"%s\", type=%p)\n",          parent, name, type);#endif /* DEBUG */ /*  * Range check input...  */  if (!type || !type->child)    return (NULL); /*  * Create the variable/argument node...  */  variable = mxmlNewElement(parent, name); /*  * Check for a default value...  */  for (node = type->child; node; node = node->next)    if (!strcmp(node->value.text.string, "="))      break;  if (node)  {   /*    * Default value found, copy it and add as a "default" attribute...    */    for (bufptr = buffer; node; bufptr += strlen(bufptr))    {      if (node->value.text.whitespace && bufptr > buffer)	*bufptr++ = ' ';      strcpy(bufptr, node->value.text.string);      next = node->next;      mxmlDelete(node);      node = next;    }    mxmlElementSetAttr(variable, "default", buffer);  } /*  * Extract the argument/variable name...  */  if (type->last_child->value.text.string[0] == ')')  {   /*    * Handle "type (*name)(args)"...    */    for (node = type->child; node; node = node->next)      if (node->value.text.string[0] == '(')	break;    for (bufptr = buffer; node; bufptr += strlen(bufptr))    {      if (node->value.text.whitespace && bufptr > buffer)	*bufptr++ = ' ';      strcpy(bufptr, node->value.text.string);      next = node->next;      mxmlDelete(node);      node = next;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -