From be96d3c60e9e52e6448bf90444eb1e8bb3a48d5c Mon Sep 17 00:00:00 2001
From: Mathias Hasselmann <mathias.hasselmann@gmx.de>
Date: Tue, 4 Sep 2007 22:44:58 +0200
Subject: [PATCH] c2xml: Implement command line options:

    -d           include document type declaration
    -p           output position information for symbols
    -o FILENAME  write the document to FILENAME
    -h           display usage information - this page

Signed-off-by: Mathias Hasselmann <mathias.hasselmann@gmx.de>
---
 c2xml.c |   79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 71 insertions(+), 8 deletions(-)

diff --git a/c2xml.c b/c2xml.c
index 36baa68..71a34a1 100644
--- a/c2xml.c
+++ b/c2xml.c
@@ -11,6 +11,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <libgen.h>
 #include <fcntl.h>
 #include <assert.h>
 #include <libxml/parser.h>
@@ -21,10 +22,16 @@
 #include "scope.h"
 #include "symbol.h"
 
+#define DTD_EXTERNAL_ID "http://www.kernel.org/pub/software/devel/sparse/parse.dtd"
+
 static xmlDocPtr doc = NULL;       /* document pointer */
 static xmlNodePtr root_node = NULL;/* root node pointer */
 static int idcount = 0;
 
+static const char *output_filename = "-";
+static int include_positions = 0;
+static int include_dtd = 0;
+
 static void examine_symbol(struct symbol *sym, xmlNodePtr node);
 
 static xmlAttrPtr newProp(xmlNodePtr node, const char *name, const char *value)
@@ -48,6 +55,9 @@ static xmlAttrPtr newIdProp(xmlNodePtr node, const char *name, unsigned int id)
 
 static void newPositionProps(xmlNodePtr node, struct position pos, struct position endpos)
 {
+	if (!include_positions)
+		return;
+
 	newProp(node, "file", stream_name(pos.stream));
 
 	newNumProp(node, "start-line", pos.line);
@@ -442,24 +452,77 @@ static void initialize_attributes()
 	init_keyword_table (-1, attribute_table, sizeof attribute_table/sizeof attribute_table[0]);
 }
 
+static void print_usage(char *arg0)
+{
+	printf("Usage: %s [OPTION]... [FILE]...\n"
+	       "Parses C code and outputs the results as XML document.\n"
+		"\n"
+		"Options:\n"
+		"  -d           include document type declaration\n"
+		"  -p           output position information for symbols\n"
+		"  -o FILENAME  write the document to FILENAME\n"
+		"  -h           display usage information - this page\n"
+		"\n"
+		"Report bugs to <linux-sparse@vger.kernel.org>\n",
+		basename(arg0));
+}
+
+static int parse_options(int argc, char **argv)
+{
+	while (1) {
+		switch (getopt (argc, argv, "hdo:p")) {
+			case 'h':
+				print_usage(argv[0]);
+				return 1;
+
+			case 'd':
+				include_dtd = 1;
+				break;
+
+			case 'o':
+				output_filename = optarg;
+				break;
+
+			case 'p':
+				include_positions = 1;
+				break;
+
+			case '?':
+				fprintf(stderr,
+					"Try `%s -h' for more information.\n",
+					basename(argv[0]));
+
+				return 2;
+
+			case -1:
+				return 0;
+		}
+	}
+}
+
 int main(int argc, char **argv)
 {
 	struct string_list *filelist = NULL;
 	struct symbol_list *symlist = NULL;
 	char *file;
 
+	xmlDtdPtr dtd;
+	xmlNsPtr ns;
+	int rc;
+
+	if (0 != (rc = parse_options(argc, argv)))
+		return rc;
+
 	doc = xmlNewDoc(BAD_CAST "1.0");
 	root_node = xmlNewNode(NULL, BAD_CAST "parse");
 	xmlDocSetRootElement(doc, root_node);
 
-/* - A DTD is probably unnecessary for something like this
-
-	dtd = xmlCreateIntSubset(doc, "parse", "http://www.kernel.org/pub/software/devel/sparse/parse.dtd" NULL, "parse.dtd");
-
-	ns = xmlNewNs (root_node, "http://www.kernel.org/pub/software/devel/sparse/parse.dtd", NULL);
+	if (include_dtd) {
+		dtd = xmlCreateIntSubset(doc, BAD_CAST "parse", BAD_CAST DTD_EXTERNAL_ID, BAD_CAST "parse.dtd");
+		ns = xmlNewNs (root_node, BAD_CAST DTD_EXTERNAL_ID, NULL);
+		xmlSetNs(root_node, ns);
+	}
 
-	xmlSetNs(root_node, ns);
-*/
 	symlist = sparse_initialize(argc, argv, &filelist);
 	initialize_attributes();
 
@@ -471,7 +534,7 @@ int main(int argc, char **argv)
 	} END_FOR_EACH_PTR_NOTAG(file);
 
 
-	xmlSaveFormatFileEnc("-", doc, "UTF-8", 1);
+	xmlSaveFormatFileEnc(output_filename, doc, "UTF-8", 1);
 	xmlFreeDoc(doc);
 	xmlCleanupParser();
 
-- 
1.5.2.3

