1#!/usr/bin/python -u
2#
3# this tests the entities substitutions with the XmlTextReader interface
4#
5import sys
6import StringIO
7import libxml2
8
9docstr="""<?xml version='1.0'?>
10<!DOCTYPE doc [
11<!ENTITY tst "<p>test</p>">
12]>
13<doc>&tst;</doc>"""
14
15# Memory debug specific
16libxml2.debugMemory(1)
17
18#
19# First test, normal don't substitute entities.
20#
21f = StringIO.StringIO(docstr)
22input = libxml2.inputBuffer(f)
23reader = input.newTextReader("test_noent")
24ret = reader.Read()
25if ret != 1:
26    print "Error reading to root"
27    sys.exit(1)
28if reader.Name() == "doc" or reader.NodeType() == 10:
29    ret = reader.Read()
30if ret != 1:
31    print "Error reading to root"
32    sys.exit(1)
33if reader.Name() != "doc" or reader.NodeType() != 1:
34    print "test_normal: Error reading the root element"
35    sys.exit(1)
36ret = reader.Read()
37if ret != 1:
38    print "test_normal: Error reading to the entity"
39    sys.exit(1)
40if reader.Name() != "tst" or reader.NodeType() != 5:
41    print "test_normal: Error reading the entity"
42    sys.exit(1)
43ret = reader.Read()
44if ret != 1:
45    print "test_normal: Error reading to the end of root"
46    sys.exit(1)
47if reader.Name() != "doc" or reader.NodeType() != 15:
48    print "test_normal: Error reading the end of the root element"
49    sys.exit(1)
50ret = reader.Read()
51if ret != 0:
52    print "test_normal: Error detecting the end"
53    sys.exit(1)
54
55#
56# Second test, completely substitute the entities.
57#
58f = StringIO.StringIO(docstr)
59input = libxml2.inputBuffer(f)
60reader = input.newTextReader("test_noent")
61reader.SetParserProp(libxml2.PARSER_SUBST_ENTITIES, 1)
62ret = reader.Read()
63if ret != 1:
64    print "Error reading to root"
65    sys.exit(1)
66if reader.Name() == "doc" or reader.NodeType() == 10:
67    ret = reader.Read()
68if ret != 1:
69    print "Error reading to root"
70    sys.exit(1)
71if reader.Name() != "doc" or reader.NodeType() != 1:
72    print "test_noent: Error reading the root element"
73    sys.exit(1)
74ret = reader.Read()
75if ret != 1:
76    print "test_noent: Error reading to the entity content"
77    sys.exit(1)
78if reader.Name() != "p" or reader.NodeType() != 1:
79    print "test_noent: Error reading the p element from entity"
80    sys.exit(1)
81ret = reader.Read()
82if ret != 1:
83    print "test_noent: Error reading to the text node"
84    sys.exit(1)
85if reader.NodeType() != 3 or reader.Value() != "test":
86    print "test_noent: Error reading the text node"
87    sys.exit(1)
88ret = reader.Read()
89if ret != 1:
90    print "test_noent: Error reading to the end of p element"
91    sys.exit(1)
92if reader.Name() != "p" or reader.NodeType() != 15:
93    print "test_noent: Error reading the end of the p element"
94    sys.exit(1)
95ret = reader.Read()
96if ret != 1:
97    print "test_noent: Error reading to the end of root"
98    sys.exit(1)
99if reader.Name() != "doc" or reader.NodeType() != 15:
100    print "test_noent: Error reading the end of the root element"
101    sys.exit(1)
102ret = reader.Read()
103if ret != 0:
104    print "test_noent: Error detecting the end"
105    sys.exit(1)
106
107#
108# third test, crazy stuff about empty element in external parsed entities
109#
110s = """<!DOCTYPE struct [
111<!ENTITY simplestruct2.ent SYSTEM "simplestruct2.ent">
112]>
113<struct>&simplestruct2.ent;</struct>
114"""
115expect="""10 struct 0 0
1161 struct 0 0
1171 descr 1 1
11815 struct 0 0
119"""
120res=""
121simplestruct2_ent="""<descr/>"""
122
123def myResolver(URL, ID, ctxt):
124    if URL == "simplestruct2.ent":
125        return(StringIO.StringIO(simplestruct2_ent))
126    return None
127
128libxml2.setEntityLoader(myResolver)
129
130input = libxml2.inputBuffer(StringIO.StringIO(s))
131reader = input.newTextReader("test3")
132reader.SetParserProp(libxml2.PARSER_SUBST_ENTITIES,1)
133while reader.Read() == 1:
134    res = res + "%s %s %d %d\n" % (reader.NodeType(),reader.Name(),
135                                   reader.Depth(),reader.IsEmptyElement())
136
137if res != expect:
138    print "test3 failed: unexpected output"
139    print res
140    sys.exit(1)
141
142#
143# cleanup
144#
145del f
146del input
147del reader
148
149# Memory debug specific
150libxml2.cleanupParser()
151if libxml2.debugMemory(1) == 0:
152    print "OK"
153else:
154    print "Memory leak %d bytes" % (libxml2.debugMemory(1))
155    libxml2.dumpMemory()
156