Commit d8cf9061 authored by Daniel Veillard's avatar Daniel Veillard

less verbose on difference cleanup fixed xmlCleanupParser() doc work on

* check-xinclude-test-suite.py: less verbose on difference
* libxml.spec.in: cleanup
* parser.c: fixed xmlCleanupParser() doc
* doc/Makefile.am doc/apibuild.py doc/libxml2-api.xml
  doc/examples/Makefile.am doc/examples/example1.c
  doc/examples/examples.xml doc/examples/index.py
  doc/examples/test1.xml: work on adding C examples and
  generating automated information about those. examples.xml
  is autogenerated describing the examples.
* example/Makefile.am: cleanup
Daniel
parent 8763df8d
Tue Nov 11 22:08:59 CET 2003 Daniel Veillard <daniel@veillard.com>
* check-xinclude-test-suite.py: less verbose on difference
* libxml.spec.in: cleanup
* parser.c: fixed xmlCleanupParser() doc
* doc/Makefile.am doc/apibuild.py doc/libxml2-api.xml
doc/examples/Makefile.am doc/examples/example1.c
doc/examples/examples.xml doc/examples/index.py
doc/examples/test1.xml: work on adding C examples and
generating automated information about those. examples.xml
is autogenerated describing the examples.
* example/Makefile.am: cleanup
Mon Nov 10 23:47:03 HKT 2003 William Brack <wbrack@mmm.com.hk>
* genUnicode.py, xmlunicode.c, include/libxml/xmlunicode.h:
......
......@@ -112,11 +112,6 @@ def runTest(test, basedir):
result = doc.serialize()
if result != expected:
print "Result for %s differs" % (id)
print '----'
print result
print '----'
print expected
print '----'
doc.freeDoc()
else:
......
......@@ -65,6 +65,9 @@
/* Define to 1 if you have the `ftime' function. */
#undef HAVE_FTIME
/* Define if getaddrinfo is there */
#undef HAVE_GETADDRINFO
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
......@@ -74,18 +77,36 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define if isinf is there */
#undef HAVE_ISINF
/* Define if isnan is there */
#undef HAVE_ISNAN
/* Define to 1 if you have the `isnand' function. */
#undef HAVE_ISNAND
/* Define if history library is there (-lhistory) */
#undef HAVE_LIBHISTORY
/* Define to 1 if you have the `inet' library (-linet). */
#undef HAVE_LIBINET
/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
/* Define if pthread library is there (-lpthread) */
#undef HAVE_LIBPTHREAD
/* Define if readline library is there (-lreadline) */
#undef HAVE_LIBREADLINE
/* Define to 1 if you have the `socket' library (-lsocket). */
#undef HAVE_LIBSOCKET
/* Have compression library */
#undef HAVE_LIBZ
/* Define to 1 if you have the `localtime' function. */
#undef HAVE_LOCALTIME
......@@ -113,6 +134,9 @@
/* Define to 1 if you have the `printf' function. */
#undef HAVE_PRINTF
/* Define if <pthread.h> is there */
#undef HAVE_PTHREAD_H
/* Define to 1 if you have the <resolv.h> header file. */
#undef HAVE_RESOLV_H
......@@ -232,8 +256,23 @@
/* Define if compiler has function prototypes */
#undef PROTOTYPES
/* Determine what socket length (socklen_t) data type is */
#undef SOCKLEN_T
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Support for IPv6 */
#undef SUPPORT_IP6
/* Version number of package */
#undef VERSION
/* Using the Win32 Socket implementation */
#undef _WINSOCKAPI_
/* Win32 Std C name mangling work-around */
#undef snprintf
/* Win32 Std C name mangling work-around */
#undef vsnprintf
......@@ -41,7 +41,7 @@ test "x$U" != "x" && AC_MSG_ERROR(Compiler not ANSI compliant)
AM_PROG_LIBTOOL
AM_MAINTAINER_MODE
# AM_MAINTAINER_MODE
dnl
dnl option to build a minimal libxml2 library
......@@ -1020,8 +1020,9 @@ rm -f COPYING.LIB COPYING
ln -s Copyright COPYING
AC_OUTPUT(libxml2.spec:libxml.spec.in Makefile include/Makefile
include/libxml/Makefile doc/Makefile example/Makefile python/Makefile
python/tests/Makefile include/libxml/xmlversion.h xml2-config libxml-2.0.pc
include/libxml/Makefile doc/Makefile doc/examples/Makefile
example/Makefile python/Makefile python/tests/Makefile
include/libxml/xmlversion.h xml2-config libxml-2.0.pc
libxml-2.0-uninstalled.pc xml2Conf.sh python/setup.py)
chmod +x xml2-config xml2Conf.sh python/setup.py
## Process this file with automake to produce Makefile.in
SUBDIRS=examples
# The name of the module.
DOC_MODULE=libxml2-$(VERSION)
......
......@@ -50,12 +50,14 @@ def escape(raw):
return raw
class identifier:
def __init__(self, name, module=None, type=None, info=None, extra=None):
def __init__(self, name, module=None, type=None, lineno = 0,
info=None, extra=None):
self.name = name
self.module = module
self.type = type
self.info = info
self.extra = extra
self.lineno = lineno
self.static = 0
def __repr__(self):
......@@ -79,9 +81,26 @@ class identifier:
self.info = info
def set_extra(self, extra):
self.extra = extra
def set_lineno(self, lineno):
self.lineno = lineno
def set_static(self, static):
self.static = static
def get_name(self):
return self.name
def get_module(self):
return self.module
def get_type(self):
return self.type
def get_info(self):
return self.info
def get_lineno(self):
return self.lineno
def get_extra(self):
return self.extra
def get_static(self):
return self.static
def update(self, module, type = None, info = None, extra=None):
if module != None and self.module == None:
self.set_module(module)
......@@ -95,7 +114,7 @@ class identifier:
class index:
def __init__(self, name = "noname"):
self.name = name;
self.name = name
self.identifiers = {}
self.functions = {}
self.variables = {}
......@@ -106,15 +125,32 @@ class index:
self.macros = {}
self.references = {}
def add(self, name, module, static, type, info=None, extra=None):
def add_ref(self, name, module, static, type, lineno, info=None, extra=None):
if name[0:2] == '__':
return None
d = None
try:
d = self.identifiers[name]
d.update(module, type, info, extra)
d.update(module, type, lineno, info, extra)
except:
d = identifier(name, module, type, info, extra)
d = identifier(name, module, type, lineno, info, extra)
self.identifiers[name] = d
if d != None and static == 1:
d.set_static(1)
if d != None and name != None and type != None:
self.references[name] = d
def add(self, name, module, static, type, lineno, info=None, extra=None):
if name[0:2] == '__':
return None
d = None
try:
d = self.identifiers[name]
d.update(module, type, lineno, info, extra)
except:
d = identifier(name, module, type, lineno, info, extra)
self.identifiers[name] = d
if d != None and static == 1:
......@@ -461,10 +497,23 @@ class CParser:
self.top_comment = ""
self.last_comment = ""
self.comment = None
self.collect_ref = 0
def collect_references(self):
self.collect_ref = 1
def lineno(self):
return self.lexer.getlineno()
def index_add(self, name, module, static, type, info=None, extra = None):
self.index.add(name, module, static, type, self.lineno(),
info, extra)
def index_add_ref(self, name, module, static, type, info=None,
extra = None):
self.index.add_ref(name, module, static, type, self.lineno(),
info, extra)
def error(self, msg, token=-1):
print "Parse Error: " + msg
if token != -1:
......@@ -679,7 +728,7 @@ class CParser:
if token == None:
return None
if token[0] == 'preproc':
self.index.add(token[1], self.filename, not self.is_header,
self.index_add(token[1], self.filename, not self.is_header,
"include")
return self.lexer.token()
return token
......@@ -701,7 +750,7 @@ class CParser:
except:
pass
info = self.parseMacroComment(name, not self.is_header)
self.index.add(name, self.filename, not self.is_header,
self.index_add(name, self.filename, not self.is_header,
"macro", info)
return token
token = self.lexer.token()
......@@ -760,15 +809,15 @@ class CParser:
type = string.split(type, '(')[0]
d = self.mergeFunctionComment(name,
((type, None), signature), 1)
self.index.add(name, self.filename, not self.is_header,
self.index_add(name, self.filename, not self.is_header,
"functype", d)
else:
if base_type == "struct":
self.index.add(name, self.filename, not self.is_header,
self.index_add(name, self.filename, not self.is_header,
"struct", type)
base_type = "struct " + name
else:
self.index.add(name, self.filename, not self.is_header,
self.index_add(name, self.filename, not self.is_header,
"typedef", type)
token = self.token()
else:
......@@ -806,7 +855,29 @@ class CParser:
token = self.token()
return token
else:
token = self.token()
if self.collect_ref == 1:
oldtok = token
token = self.token()
if oldtok[0] == "name" and oldtok[1][0:3] == "xml":
if token[0] == "sep" and token[1] == "(":
self.index_add_ref(oldtok[1], self.filename,
0, "function")
token = self.token()
elif token[0] == "name":
token = self.token()
if token[0] == "sep" and (token[1] == ";" or
token[1] == "," or token[1] == "="):
self.index_add_ref(oldtok[1], self.filename,
0, "type")
elif oldtok[0] == "name" and oldtok[1][0:4] == "XML_":
self.index_add_ref(oldtok[1], self.filename,
0, "typedef")
elif oldtok[0] == "name" and oldtok[1][0:7] == "LIBXML_":
self.index_add_ref(oldtok[1], self.filename,
0, "typedef")
else:
token = self.token()
return token
#
......@@ -1009,7 +1080,7 @@ class CParser:
else:
enum_type = token[1]
for enum in self.enums:
self.index.add(enum[0], self.filename,
self.index_add(enum[0], self.filename,
not self.is_header, "enum",
(enum[1], enum[2], enum_type))
return token
......@@ -1207,10 +1278,10 @@ class CParser:
self.comment = None
token = self.token()
if type == "struct":
self.index.add(self.name, self.filename,
self.index_add(self.name, self.filename,
not self.is_header, "struct", self.struct_fields)
else:
self.index.add(self.name, self.filename,
self.index_add(self.name, self.filename,
not self.is_header, "variable", type)
break
elif token[1] == "(":
......@@ -1221,19 +1292,19 @@ class CParser:
if token[0] == "sep" and token[1] == ";":
d = self.mergeFunctionComment(self.name,
((type, None), self.signature), 1)
self.index.add(self.name, self.filename, static,
self.index_add(self.name, self.filename, static,
"function", d)
token = self.token()
elif token[0] == "sep" and token[1] == "{":
d = self.mergeFunctionComment(self.name,
((type, None), self.signature), static)
self.index.add(self.name, self.filename, static,
self.index_add(self.name, self.filename, static,
"function", d)
token = self.token()
token = self.parseBlock(token);
elif token[1] == ',':
self.comment = None
self.index.add(self.name, self.filename, static,
self.index_add(self.name, self.filename, static,
"variable", type)
type = type_orig
token = self.token()
......
Makefile.in
Makefile
example1
noinst_PROGRAMS=example1
INCLUDES = -I$(top_builddir)/include -I@srcdir@/include @THREAD_CFLAGS@ @Z_CFLAGS@
DEPS = $(top_builddir)/libxml2.la
LDADDS = @STATIC_BINARIES@ $(top_builddir)/libxml2.la @THREAD_LIBS@ @Z_LIBS@ $(ICONV_LIBS) -lm @WIN32_EXTRA_LIBADD@
EXTRA_DIST=examples.xml test1.xml
example1_SOURCES=example1.c
example1_LDFLAGS =
example1_DEPENDENCIES = $(DEPS)
example1_LDADD= @RDL_LIBS@ $(LDADDS)
all: examples.xml
examples.xml: index.py *.c
-@($(srcdir)/index.py)
/**
* purpose: Demonstrate the use of xmlReadFile() to read an XML file
* into a tree and and xmlFreeDoc() to free the resulting tree
* usage: example1 test1.xml
* author: daniel@veillard.com
* copy: see Copyright for the status of this software.
*/
#include <stdio.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
/**
* example1Func:
* @filename: a filename or an URL
*
* Parse the resource and free the resulting tree
*/
static void
example1Func(const char *filename) {
xmlDocPtr doc; /* the resulting document tree */
doc = xmlReadFile(filename, NULL, 0);
if (doc == NULL) {
fprintf(stderr, "Failed to parse %s\n", filename);
return;
}
xmlFreeDoc(doc);
}
int main(int argc, char **argv) {
if (argc != 2)
return(1);
/*
* this initialize the library and check potential ABI mismatches
* between the version it was compiled for and the actual shared
* library used.
*/
LIBXML_TEST_VERSION
example1Func(argv[1]);
/*
* Cleanup function for the XML library.
*/
xmlCleanupParser();
return(0);
}
<examples>
<example filename='example1.c'>
<purpose>Demonstrate the use of xmlReadFile() to read an XML file into a tree and and xmlFreeDoc() to free the resulting tree</purpose>
<usage>example1 test1.xml</usage>
<author>daniel@veillard.com</author>
<copy>see Copyright for the status of this software. </copy>
<uses>
<include>&lt;libxml/tree.h&gt;</include>
<include>&lt;libxml/parser.h&gt;</include>
<function line='47' file='parser'>xmlCleanupParser</function>
<macro line='42' file='xmlversion'>LIBXML_TEST_VERSION</macro>
<function line='28' file='tree'>xmlFreeDoc</function>
<function line='23' file='parser'>xmlReadFile</function>
<typedef line='21' file='tree'>xmlDocPtr</typedef>
</uses>
</example>
<symbols>
<symbol name='LIBXML_TEST_VERSION'>
<ref filename='example1.c'/>
</symbol>
<symbol name='xmlCleanupParser'>
<ref filename='example1.c'/>
</symbol>
<symbol name='xmlDocPtr'>
<ref filename='example1.c'/>
</symbol>
<symbol name='xmlFreeDoc'>
<ref filename='example1.c'/>
</symbol>
<symbol name='xmlReadFile'>
<ref filename='example1.c'/>
</symbol>
</symbols>
</examples>
#!/usr/bin/python -u
#
# Indexes the examples and build doc and web pages.
#
import string
import sys
try:
import libxml2
except:
sys.exit(1)
sys.path.append("..")
from apibuild import CParser, escape
symbols = {}
api_dict = None
api_doc = None
def load_api():
global api_dict
global api_doc
if api_dict != None:
return
api_dict = {}
try:
print "loading ../libxml2-api.xml"
api_doc = libxml2.parseFile("../libxml2-api.xml")
except:
print "failed to parse ../libxml2-api.xml"
sys.exit(1)
def find_symbol(name):
global api_dict
global api_doc
if api_doc == None:
load_api()
if name == None:
return
if api_dict.has_key(name):
return api_dict[name]
ctxt = api_doc.xpathNewContext()
res = ctxt.xpathEval("/api/symbols/*[@name = '%s']" % (name))
if type(res) == type([]) and len(res) >= 1:
if len(res) > 1:
print "Found %d references to %s in the API" % (len(res), name)
node = res[0]
typ = node.name
file = node.xpathEval("string(@file)")
info = node.xpathEval("string(info)")
else:
print "Reference %s not found in the API" % (name)
return None
ret = (typ, file, info)
api_dict[name] = ret
return ret
def parse_top_comment(filename, comment):
res = {}
lines = string.split(comment, "\n")
item = None
for line in lines:
while line != "" and line[0] == ' ':
line = line[1:]
while line != "" and line[0] == '*':
line = line[1:]
while line != "" and line[0] == ' ':
line = line[1:]
try:
(it, line) = string.split(line, ":", 1)
item = it
while line != "" and line[0] == ' ':
line = line[1:]
if res.has_key(item):
res[item] = res[item] + " " + line
else:
res[item] = line
except:
if item != None:
if res.has_key(item):
res[item] = res[item] + " " + line
else:
res[item] = line
return res
def parse(filename, output):
global symbols
parser = CParser(filename)
parser.collect_references()
idx = parser.parse()
info = parse_top_comment(filename, parser.top_comment)
output.write(" <example filename='%s'>\n" % filename)
try:
purpose = info['purpose']
output.write(" <purpose>%s</purpose>\n" % purpose);
except:
print "Example %s lacks a purpose description" % (filename)
try:
usage = info['usage']
output.write(" <usage>%s</usage>\n" % usage);
except:
print "Example %s lacks an usage description" % (filename)
try:
author = info['author']
output.write(" <author>%s</author>\n" % author);
except:
print "Example %s lacks an author description" % (filename)
try:
copy = info['copy']
output.write(" <copy>%s</copy>\n" % copy);
except:
print "Example %s lacks a copyright description" % (filename)
for topic in info.keys():
if topic != "purpose" and topic != "usage" and \
topic != "author" and topic != "copy":
str = info[topic]
output.write(" <extra topic='%s'>%s</extra>\n" % str)
# print idx.functions
output.write(" <uses>\n")
for include in idx.includes.keys():
if include.find("libxml") != -1:
output.write(" <include>%s</include>\n" % (escape(include)))
for ref in idx.references.keys():
id = idx.references[ref]
name = id.get_name()
line = id.get_lineno()
if symbols.has_key(name):
sinfo = symbols[name]
refs = sinfo[0]
# gather at most 5 references per symbols
if refs > 5:
continue
sinfo[refs] = filename
sinfo[0] = refs + 1
else:
symbols[name] = [1, filename]
info = find_symbol(name)
if info != None:
type = info[0]
file = info[1]
output.write(" <%s line='%d' file='%s'>%s</%s>\n" % (type,
line, file, name, type))
else:
type = id.get_type()
output.write(" <%s line='%d'>%s</%s>\n" % (type,
line, name, type))
output.write(" </uses>\n")
output.write(" </example>\n")
return idx
def dump_symbols(output):
global symbols
output.write(" <symbols>\n")
keys = symbols.keys()
keys.sort()
for symbol in keys:
output.write(" <symbol name='%s'>\n" % (symbol))
info = symbols[symbol]
i = 1
while i < len(info):
output.write(" <ref filename='%s'/>\n" % (info[i]))
i = i + 1
output.write(" </symbol>\n")
output.write(" </symbols>\n")
if __name__ == "__main__":
load_api()
output = open("examples.xml", "w")
output.write("<examples>\n")
parse("example1.c", output)
dump_symbols(output)