rgen 0.5.4 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/CHANGELOG +28 -0
  2. data/Rakefile +3 -4
  3. data/lib/ea_support/uml13_ea_metamodel.rb +3 -3
  4. data/lib/ea_support/uml13_ea_to_uml13.rb +33 -2
  5. data/lib/ea_support/uml13_to_uml13_ea.rb +7 -0
  6. data/lib/mmgen/mm_ext/ecore_mmgen_ext.rb +4 -4
  7. data/lib/mmgen/templates/metamodel_generator.tpl +143 -143
  8. data/lib/rgen/ecore/ecore.rb +11 -1
  9. data/lib/rgen/ecore/ecore_interface.rb +47 -0
  10. data/lib/rgen/ecore/ecore_to_ruby.rb +166 -0
  11. data/lib/rgen/ecore/{ecore_transformer.rb → ruby_to_ecore.rb} +11 -11
  12. data/lib/rgen/environment.rb +15 -2
  13. data/lib/rgen/fragment/dump_file_cache.rb +63 -0
  14. data/lib/rgen/fragment/fragmented_model.rb +139 -0
  15. data/lib/rgen/fragment/model_fragment.rb +268 -0
  16. data/lib/rgen/instantiator/abstract_xml_instantiator.rb +44 -72
  17. data/lib/rgen/instantiator/default_xml_instantiator.rb +2 -2
  18. data/lib/rgen/instantiator/ecore_xml_instantiator.rb +16 -1
  19. data/lib/rgen/instantiator/json_instantiator.rb +16 -2
  20. data/lib/rgen/instantiator/nodebased_xml_instantiator.rb +118 -138
  21. data/lib/rgen/instantiator/qualified_name_resolver.rb +5 -1
  22. data/lib/rgen/instantiator/reference_resolver.rb +126 -24
  23. data/lib/rgen/instantiator/xmi11_instantiator.rb +6 -2
  24. data/lib/rgen/metamodel_builder.rb +18 -6
  25. data/lib/rgen/metamodel_builder/builder_extensions.rb +431 -407
  26. data/lib/rgen/metamodel_builder/builder_runtime.rb +8 -8
  27. data/lib/rgen/metamodel_builder/constant_order_helper.rb +4 -4
  28. data/lib/rgen/metamodel_builder/data_types.rb +5 -1
  29. data/lib/rgen/metamodel_builder/intermediate/feature.rb +167 -0
  30. data/lib/rgen/metamodel_builder/module_extension.rb +2 -2
  31. data/lib/rgen/model_builder.rb +10 -5
  32. data/lib/rgen/model_builder/builder_context.rb +17 -1
  33. data/lib/rgen/serializer/opposite_reference_filter.rb +18 -0
  34. data/lib/rgen/serializer/qualified_name_provider.rb +45 -0
  35. data/lib/rgen/template_language/template_container.rb +3 -1
  36. data/lib/rgen/{auto_class_creator.rb → util/auto_class_creator.rb} +6 -1
  37. data/lib/rgen/util/cached_glob.rb +67 -0
  38. data/lib/rgen/util/file_cache_map.rb +104 -0
  39. data/lib/rgen/util/file_change_detector.rb +78 -0
  40. data/lib/rgen/{method_delegation.rb → util/method_delegation.rb} +18 -3
  41. data/lib/rgen/{model_comparator.rb → util/model_comparator.rb} +17 -5
  42. data/lib/rgen/{model_comparator_base.rb → util/model_comparator_base.rb} +6 -1
  43. data/lib/rgen/{model_dumper.rb → util/model_dumper.rb} +6 -1
  44. data/lib/rgen/{name_helper.rb → util/name_helper.rb} +6 -1
  45. data/lib/rgen/util/pattern_matcher.rb +329 -0
  46. data/lib/transformers/uml13_to_ecore.rb +103 -60
  47. data/test/ecore_self_test.rb +43 -42
  48. data/test/json_test.rb +15 -0
  49. data/test/metamodel_builder_test.rb +361 -206
  50. data/test/metamodel_from_ecore_test.rb +45 -0
  51. data/test/metamodel_order_test.rb +10 -4
  52. data/test/metamodel_roundtrip_test.rb +2 -2
  53. data/test/metamodel_roundtrip_test/TestModel_Regenerated.rb +1 -1
  54. data/test/metamodel_roundtrip_test/houseMetamodel_Regenerated.ecore +50 -50
  55. data/test/method_delegation_test.rb +9 -9
  56. data/test/model_builder/ecore_internal.rb +19 -9
  57. data/test/model_builder/serializer_test.rb +1 -1
  58. data/test/reference_resolver_test.rb +79 -12
  59. data/test/rgen_test.rb +2 -0
  60. data/test/template_language_test.rb +7 -0
  61. data/test/template_language_test/templates/callback_indent_test/a.tpl +12 -0
  62. data/test/template_language_test/templates/callback_indent_test/b.tpl +5 -0
  63. data/test/testmodel/ea_testmodel_regenerated.xml +588 -583
  64. data/test/transformer_test.rb +3 -3
  65. data/test/util/file_cache_map_test.rb +91 -0
  66. data/test/util/file_cache_map_test/testdir/fileA +1 -0
  67. data/test/util_test.rb +4 -0
  68. data/test/xml_instantiator_test.rb +139 -135
  69. metadata +49 -104
  70. data/lib/rgen/ecore/ecore_instantiator.rb +0 -31
  71. data/lib/rgen/metamodel_builder/metamodel_description.rb +0 -232
  72. data/redist/xmlscan/ChangeLog +0 -1301
  73. data/redist/xmlscan/README +0 -34
  74. data/redist/xmlscan/THANKS +0 -11
  75. data/redist/xmlscan/doc/changes.html +0 -74
  76. data/redist/xmlscan/doc/changes.rd +0 -80
  77. data/redist/xmlscan/doc/en/conformance.html +0 -136
  78. data/redist/xmlscan/doc/en/conformance.rd +0 -152
  79. data/redist/xmlscan/doc/en/manual.html +0 -356
  80. data/redist/xmlscan/doc/en/manual.rd +0 -402
  81. data/redist/xmlscan/doc/ja/conformance.ja.html +0 -118
  82. data/redist/xmlscan/doc/ja/conformance.ja.rd +0 -134
  83. data/redist/xmlscan/doc/ja/manual.ja.html +0 -325
  84. data/redist/xmlscan/doc/ja/manual.ja.rd +0 -370
  85. data/redist/xmlscan/doc/src/Makefile +0 -41
  86. data/redist/xmlscan/doc/src/conformance.rd.src +0 -256
  87. data/redist/xmlscan/doc/src/langsplit.rb +0 -110
  88. data/redist/xmlscan/doc/src/manual.rd.src +0 -614
  89. data/redist/xmlscan/install.rb +0 -41
  90. data/redist/xmlscan/lib/xmlscan/encoding.rb +0 -311
  91. data/redist/xmlscan/lib/xmlscan/htmlscan.rb +0 -289
  92. data/redist/xmlscan/lib/xmlscan/namespace.rb +0 -352
  93. data/redist/xmlscan/lib/xmlscan/parser.rb +0 -299
  94. data/redist/xmlscan/lib/xmlscan/scanner.rb +0 -1109
  95. data/redist/xmlscan/lib/xmlscan/version.rb +0 -22
  96. data/redist/xmlscan/lib/xmlscan/visitor.rb +0 -158
  97. data/redist/xmlscan/lib/xmlscan/xmlchar.rb +0 -441
  98. data/redist/xmlscan/memo/CONFORMANCE +0 -1249
  99. data/redist/xmlscan/memo/PRODUCTIONS +0 -195
  100. data/redist/xmlscan/memo/contentspec.ry +0 -335
  101. data/redist/xmlscan/samples/chibixml.rb +0 -105
  102. data/redist/xmlscan/samples/getxmlchar.rb +0 -122
  103. data/redist/xmlscan/samples/rexml.rb +0 -159
  104. data/redist/xmlscan/samples/xmlbench.rb +0 -88
  105. data/redist/xmlscan/samples/xmlbench/parser/chibixml.rb +0 -22
  106. data/redist/xmlscan/samples/xmlbench/parser/nqxml.rb +0 -29
  107. data/redist/xmlscan/samples/xmlbench/parser/rexml.rb +0 -62
  108. data/redist/xmlscan/samples/xmlbench/parser/xmlparser.rb +0 -22
  109. data/redist/xmlscan/samples/xmlbench/parser/xmlscan-0.0.10.rb +0 -62
  110. data/redist/xmlscan/samples/xmlbench/parser/xmlscan-chibixml.rb +0 -22
  111. data/redist/xmlscan/samples/xmlbench/parser/xmlscan-rexml.rb +0 -22
  112. data/redist/xmlscan/samples/xmlbench/parser/xmlscan.rb +0 -99
  113. data/redist/xmlscan/samples/xmlbench/xmlbench-lib.rb +0 -116
  114. data/redist/xmlscan/samples/xmlconftest.rb +0 -200
  115. data/redist/xmlscan/test.rb +0 -7
  116. data/redist/xmlscan/tests/deftestcase.rb +0 -73
  117. data/redist/xmlscan/tests/runtest.rb +0 -47
  118. data/redist/xmlscan/tests/testall.rb +0 -14
  119. data/redist/xmlscan/tests/testencoding.rb +0 -438
  120. data/redist/xmlscan/tests/testhtmlscan.rb +0 -752
  121. data/redist/xmlscan/tests/testnamespace.rb +0 -457
  122. data/redist/xmlscan/tests/testparser.rb +0 -591
  123. data/redist/xmlscan/tests/testscanner.rb +0 -1749
  124. data/redist/xmlscan/tests/testxmlchar.rb +0 -143
  125. data/redist/xmlscan/tests/visitor.rb +0 -34
@@ -1,352 +0,0 @@
1
- #
2
- # xmlscan/namespace.rb
3
- #
4
- # Copyright (C) Ueno Katsuhiro 2002
5
- #
6
- # $Id: namespace.rb,v 1.13 2003/01/22 13:06:18 katsu Exp $
7
- #
8
-
9
- require 'xmlscan/parser'
10
-
11
-
12
- module XMLScan
13
-
14
- class NSParseError < ParseError ; end
15
- class NSNotWellFormedError < NotWellFormedError ; end
16
- class NSNotValidError < NotValidError ; end
17
-
18
-
19
- module NSVisitor
20
-
21
- include Visitor
22
-
23
- def ns_parse_error(msg)
24
- raise NSParseError.new(msg)
25
- end
26
-
27
- def ns_wellformed_error(msg)
28
- raise NSNotWellFormedError.new(msg)
29
- end
30
-
31
- def ns_valid_error(msg)
32
- raise NSNotValidError.new(msg)
33
- end
34
-
35
- #
36
- # <foo:bar hoge:fuga='' hoge='' >
37
- # <foo hoge:fuga='' hoge='' >
38
- # ^ ^ ^ ^ ^ ^
39
- # 1 2 3 4 5 6
40
- #
41
- # The following method will be called with the following arguments
42
- # when the parser reaches the above point;
43
- #
44
- # 1: on_stag_ns ('foo:bar', 'foo', 'bar')
45
- # or
46
- # on_stag_ns ('foo', '', 'foo')
47
- # 2: on_attribute_ns ('hoge:fuga', 'hoge', 'fuga')
48
- # 3: on_attribute_end ('hoge:fuga')
49
- # 4: on_attribute_ns ('hoge', nil, 'hoge')
50
- # 5: on_attribute_end ('hoge')
51
- # 6: on_stag_end_ns ('foo:bar', { 'foo' => '', ... })
52
- # or
53
- # on_stag_end_empty_ns ('foo:bar', { 'foo' => '', ... })
54
- #
55
-
56
- def on_stag_ns(qname, prefix, localpart)
57
- end
58
-
59
- def on_attribute_ns(qname, prefix, localpart)
60
- end
61
-
62
- def on_stag_end_ns(qname, namespaces)
63
- end
64
-
65
- def on_stag_end_empty_ns(qname, namespaces)
66
- end
67
-
68
- end
69
-
70
-
71
-
72
-
73
- class XMLNamespaceDecoration < Decoration
74
-
75
- proc {
76
- h = {'foo'=>true} ; h['foo'] = nil
77
- raise "requires Ruby-1.6 or above" unless h.key? 'foo'
78
- }.call
79
-
80
- PredefinedNamespace = {
81
- 'xml' => 'http://www.w3.org/XML/1998/namespace',
82
- 'xmlns' => 'http://www.w3.org/2000/xmlns/',
83
- }
84
-
85
- ReservedNamespace = PredefinedNamespace.invert
86
-
87
-
88
- def ns_parse_error(msg)
89
- @orig_visitor.ns_parse_error msg
90
- end
91
-
92
- def ns_wellformed_error(msg)
93
- @orig_visitor.ns_wellformed_error msg
94
- end
95
-
96
- def ns_valid_error(msg)
97
- @orig_visitor.ns_valid_error msg
98
- end
99
-
100
-
101
- def on_start_document
102
- @namespace = {} #PredefinedNamespace.dup
103
- @ns_hist = []
104
- @ns_undeclared = {} # for checking undeclared namespace prefixes.
105
- @prev_prefix = {} # for checking doubled attributes.
106
- @dont_same = [] # ditto.
107
- @xmlns = NamespaceDeclaration.new(self)
108
- @orig_visitor = @visitor
109
- @visitor.on_start_document
110
- end
111
-
112
-
113
- def on_stag(name)
114
- @ns_hist.push nil
115
- unless /:/n =~ name then
116
- @visitor.on_stag_ns name, '', name
117
- else
118
- prefix, localpart = $`, $'
119
- if localpart.include? ?: then
120
- ns_parse_error "localpart `#{localpart}' includes `:'"
121
- end
122
- if prefix == 'xmlns' then
123
- ns_wellformed_error \
124
- "prefix `xmlns' is not used for namespace prefix declaration"
125
- end
126
- unless @namespace.key? prefix then
127
- if uri = PredefinedNamespace[prefix] then
128
- @namespace[prefix] = uri
129
- else
130
- @ns_undeclared[prefix] = true
131
- end
132
- end
133
- @visitor.on_stag_ns name, prefix, localpart
134
- end
135
- end
136
-
137
-
138
- def on_attribute(name)
139
- if /:/n =~ name then
140
- prefix, localpart = $`, $'
141
- if localpart.include? ?: then
142
- ns_parse_error "localpart `#{localpart}' includes `:'"
143
- end
144
- unless @namespace.key? prefix then
145
- if uri = PredefinedNamespace[prefix] then
146
- @namespace[prefix] = uri
147
- else
148
- @ns_undeclared[prefix] = true
149
- end
150
- end
151
- if prefix == 'xmlns' then
152
- @visitor = @xmlns
153
- @xmlns.on_xmlns_start localpart
154
- else
155
- if prev = @prev_prefix[localpart] then
156
- @dont_same.push [ prev, prefix, localpart ]
157
- end
158
- @prev_prefix[localpart] = prefix
159
- @visitor.on_attribute_ns name, prefix, localpart
160
- end
161
- elsif name == 'xmlns' then
162
- @visitor = @xmlns
163
- @xmlns.on_xmlns_start ''
164
- else
165
- @visitor.on_attribute_ns name, nil, name
166
- end
167
- end
168
-
169
-
170
- class NamespaceDeclaration
171
-
172
- include XMLScan::Visitor
173
-
174
- def initialize(parent)
175
- @parent = parent
176
- end
177
-
178
- def on_xmlns_start(prefix)
179
- @prefix = prefix
180
- @nsdecl = ''
181
- end
182
-
183
- def on_attr_value(str)
184
- @nsdecl << str
185
- end
186
-
187
- def on_attr_entityref(ref)
188
- @parent.ns_wellformed_error \
189
- "xmlns includes undeclared entity reference"
190
- end
191
-
192
- def on_attr_charref(code)
193
- @nsdecl << [code].pack('U')
194
- end
195
-
196
- def on_attr_charref_hex(code)
197
- @nsdecl << [code].pack('U')
198
- end
199
-
200
- def on_attribute_end(name)
201
- @parent.on_xmlns_end @prefix, @nsdecl
202
- end
203
-
204
- end
205
-
206
-
207
- def on_xmlns_end(prefix, uri)
208
- @visitor = @orig_visitor
209
- if PredefinedNamespace.key? prefix then
210
- if prefix == 'xmlns' then
211
- ns_wellformed_error \
212
- "prefix `xmlns' can't be bound to any namespace explicitly"
213
- elsif (s = PredefinedNamespace[prefix]) != uri then
214
- ns_wellformed_error \
215
- "prefix `#{prefix}' can't be bound to any namespace except `#{s}'"
216
- end
217
- end
218
- if uri.empty? then
219
- if prefix.empty? then
220
- uri = nil
221
- else
222
- ns_parse_error "`#{prefix}' is bound to empty namespace name"
223
- end
224
- elsif ReservedNamespace.key? uri then
225
- unless (s = ReservedNamespace[uri]) == prefix then
226
- ns_wellformed_error \
227
- "namespace `#{uri}' is reserved for prefix `#{s}'"
228
- end
229
- end
230
- (@ns_hist.last || @ns_hist[-1] = {})[prefix] = @namespace[prefix]
231
- @namespace[prefix] = uri
232
- @ns_undeclared.delete prefix
233
- end
234
-
235
-
236
- def fix_namespace
237
- unless @ns_undeclared.empty? then
238
- @ns_undeclared.each_key { |i|
239
- @visitor.ns_wellformed_error "prefix `#{i}' is not declared"
240
- }
241
- @ns_undeclared.clear
242
- end
243
- unless @dont_same.empty? then
244
- @dont_same.each { |n1,n2,l|
245
- if @namespace[n1] == @namespace[n2] then
246
- ns_wellformed_error \
247
- "doubled localpart `#{l}' in the same namespace"
248
- end
249
- }
250
- @dont_same.clear
251
- end
252
- @prev_prefix.clear
253
- end
254
-
255
-
256
- def on_stag_end(name)
257
- fix_namespace
258
- @visitor.on_stag_end_ns name, @namespace
259
- end
260
-
261
-
262
- def on_etag(name)
263
- h = @ns_hist.pop and @namespace.update h
264
- @visitor.on_etag name
265
- end
266
-
267
-
268
- def on_stag_end_empty(name)
269
- fix_namespace
270
- @visitor.on_stag_end_empty_ns name, @namespace
271
- h = @ns_hist.pop and @namespace.update h
272
- end
273
-
274
-
275
- def on_doctype(root, pubid, sysid)
276
- if root.count(':') > 1 then
277
- ns_parse_error "qualified name `#{root}' includes `:'"
278
- end
279
- @visitor.on_doctype root, pubid, sysid
280
- end
281
-
282
-
283
- def on_pi(target, pi)
284
- if target.include? ?: then
285
- ns_parse_error "PI target `#{target}' includes `:'"
286
- end
287
- @visitor.on_pi target, pi
288
- end
289
-
290
-
291
- def on_entityref(ref)
292
- if ref.include? ?: then
293
- ns_parse_error "entity reference `#{ref}' includes `:'"
294
- end
295
- @visitor.on_entityref ref
296
- end
297
-
298
-
299
- def on_attr_entityref(ref)
300
- if ref.include? ?: then
301
- ns_parse_error "entity reference `#{ref}' includes `:'"
302
- end
303
- @visitor.on_attr_entityref ref
304
- end
305
-
306
- end
307
-
308
-
309
-
310
- class XMLParserNS < XMLParser
311
-
312
- def initialize(*)
313
- super
314
- @visitor = @decoration = XMLNamespaceDecoration.new(@visitor)
315
- end
316
-
317
- end
318
-
319
- end
320
-
321
-
322
-
323
-
324
-
325
- if $0 == __FILE__ then
326
- class TestVisitor
327
- include XMLScan::NSVisitor
328
- def parse_error(msg)
329
- STDERR.printf("%s:%d: %s\n", $s.path, $s.lineno, msg) if $VERBOSE
330
- end
331
- def wellformed_error(msg)
332
- STDERR.printf("%s:%d: WFC: %s\n", $s.path, $s.lineno, msg) if $VERBOSE
333
- end
334
- def warning(msg)
335
- STDERR.printf("%s:%d: warning: %s\n", $s.path,$s.lineno, msg) if $VERBOSE
336
- end
337
- def ns_parse_error(msg)
338
- STDERR.printf("%s:%d: %s\n", $s.path, $s.lineno, msg) if $VERBOSE
339
- end
340
- def ns_wellformed_error(msg)
341
- STDERR.printf("%s:%d: NSC: %s\n", $s.path, $s.lineno, msg) if $VERBOSE
342
- end
343
- end
344
-
345
- $s = scan = XMLScan::XMLParserNS.new(TestVisitor.new)
346
- src = ARGF
347
- def src.path; filename; end
348
- t1 = Time.times.utime
349
- scan.parse src
350
- t2 = Time.times.utime
351
- STDERR.printf "%2.3f sec\n", t2 - t1
352
- end
@@ -1,299 +0,0 @@
1
- #
2
- # xmlscan/parser.rb
3
- #
4
- # Copyright (C) Ueno Katsuhiro 2002
5
- #
6
- # $Id: parser.rb,v 1.10 2003/01/22 13:06:18 katsu Exp $
7
- #
8
-
9
- require 'xmlscan/scanner'
10
-
11
-
12
- module XMLScan
13
-
14
- class XMLParser < XMLScanner
15
-
16
- class AttributeChecker < Hash
17
- # AttributeChecker inherits Hash only for speed.
18
-
19
- def check_unique(name)
20
- not key? name and store(name, true)
21
- end
22
-
23
- end
24
-
25
-
26
- #PredefinedEntity = {
27
- # 'lt' => '<',
28
- # 'gt' => '>',
29
- # 'amp' => '&',
30
- # 'quot' => '"',
31
- # 'apos' => "'",
32
- #}
33
-
34
-
35
- def parse(*)
36
- @elem = []
37
- @attr = AttributeChecker.new
38
- @standalone = nil
39
- super
40
- end
41
-
42
-
43
- private
44
-
45
- def on_xmldecl_version(str)
46
- unless str == '1.0' then
47
- warning "unsupported XML version `#{str}'"
48
- end
49
- @visitor.on_xmldecl_version str
50
- end
51
-
52
-
53
- def on_xmldecl_standalone(str)
54
- if str == 'yes' then
55
- @standalone = true
56
- elsif str == 'no' then
57
- @standalone = false
58
- else
59
- parse_error "standalone declaration must be either `yes' or `no'"
60
- end
61
- @visitor.on_xmldecl_standalone str
62
- end
63
-
64
-
65
- def on_doctype(name, pubid, sysid)
66
- if pubid and not sysid then
67
- parse_error "public external ID must have both public ID and system ID"
68
- end
69
- @visitor.on_doctype name, pubid, sysid
70
- end
71
-
72
-
73
- def on_prolog_space(s)
74
- # just ignore it.
75
- end
76
-
77
-
78
- def on_pi(target, pi)
79
- if target.downcase == 'xml' then
80
- parse_error "reserved PI target `#{target}'"
81
- end
82
- @visitor.on_pi target, pi
83
- end
84
-
85
-
86
- #def on_entityref(ref)
87
- # rep = PredefinedEntity[ref]
88
- # if rep then
89
- # @visitor.on_chardata rep
90
- # else
91
- # @visitor.on_entityref ref
92
- # end
93
- #end
94
-
95
-
96
- #def on_attr_entityref(ref)
97
- # rep = PredefinedEntity[ref]
98
- # if rep then
99
- # @visitor.on_attr_value rep
100
- # else
101
- # @visitor.on_attr_entityref ref
102
- # end
103
- #end
104
-
105
-
106
- #def on_charref_hex(code)
107
- # on_charref code
108
- #end
109
-
110
-
111
- #def on_attr_charref_hex(code)
112
- # on_attr_charref code
113
- #end
114
-
115
-
116
- def on_stag(name)
117
- @elem.push name
118
- @visitor.on_stag name
119
- @attr.clear
120
- end
121
-
122
- def on_attribute(name)
123
- unless @attr.check_unique name then
124
- wellformed_error "doubled attribute `#{name}'"
125
- end
126
- @visitor.on_attribute name
127
- end
128
-
129
- def on_attr_value(str)
130
- str.tr! "\t\r\n", ' ' # normalize
131
- @visitor.on_attr_value str
132
- end
133
-
134
- def on_stag_end_empty(name)
135
- # @visitor.on_stag_end name
136
- # @elem.pop
137
- # @visitor.on_etag name
138
- @visitor.on_stag_end_empty name
139
- @elem.pop
140
- end
141
-
142
- def on_etag(name)
143
- last = @elem.pop
144
- if last == name then
145
- @visitor.on_etag name
146
- elsif last then
147
- wellformed_error "element type `#{name}' is not matched"
148
- @visitor.on_etag last
149
- else
150
- parse_error "end tag `#{name}' appears alone"
151
- end
152
- end
153
-
154
-
155
- public
156
-
157
-
158
- def scan_content(s)
159
- elem = @elem # for speed
160
- src = @src # for speed
161
- found_root_element = false
162
-
163
- begin
164
-
165
- # -- first start tag --
166
- elem.clear
167
- found_stag = false
168
-
169
- while s and not found_stag
170
- if (c = s[0]) == ?< then
171
- if (c = s[1]) == ?/ then
172
- # should be a parse error
173
- scan_etag s
174
- elsif c == ?! then
175
- if s[2] == ?- and s[3] == ?- then
176
- scan_comment s
177
- elsif /\A<!\[CDATA\[/n =~ s then
178
- parse_error "CDATA section is found outside of root element"
179
- scan_cdata $'
180
- else
181
- scan_bang_tag s
182
- end
183
- elsif c == ?? then
184
- scan_pi s
185
- else
186
- found_root_element = true
187
- found_stag = true
188
- scan_stag s
189
- end
190
- else
191
- parse_error "content of element is found outside of root element"
192
- scan_chardata s
193
- end
194
- s = src.get
195
- end
196
-
197
- if not found_root_element and not found_stag then
198
- parse_error "no root element was found"
199
- end
200
-
201
- # -- contents --
202
- while s and not elem.empty?
203
- if (c = s[0]) == ?< then
204
- if (c = s[1]) == ?/ then
205
- scan_etag s
206
- elsif c == ?! then
207
- if s[2] == ?- and s[3] == ?- then
208
- scan_comment s
209
- elsif /\A<!\[CDATA\[/n =~ s then
210
- scan_cdata $'
211
- else
212
- scan_bang_tag s
213
- end
214
- elsif c == ?? then
215
- scan_pi s
216
- else
217
- scan_stag s
218
- end
219
- else
220
- scan_chardata s
221
- end
222
- s = src.get
223
- end
224
-
225
- unless elem.empty? then
226
- while name = elem.pop
227
- parse_error "unclosed element `#{name}' meets EOF"
228
- @visitor.on_etag name
229
- end
230
- end
231
-
232
- # -- epilogue --
233
- finish = true
234
-
235
- while s
236
- if (c = s[0]) == ?< then
237
- if (c = s[1]) == ?/ then
238
- finish = false # content out of root element
239
- break
240
- elsif c == ?! then
241
- if s[2] == ?- and s[3] == ?- then
242
- scan_comment s
243
- else
244
- finish = false # content out of root element
245
- break
246
- end
247
- elsif c == ?? then
248
- scan_pi s
249
- else
250
- parse_error "another root element is found" # stag
251
- finish = false
252
- break
253
- end
254
- else
255
- if s.strip.empty? then
256
- on_prolog_space s
257
- else
258
- finish = false # content out of root element
259
- break
260
- end
261
- end
262
- s = src.get
263
- end
264
-
265
- end until finish
266
-
267
- end
268
- end
269
-
270
-
271
- end
272
-
273
-
274
-
275
-
276
-
277
-
278
- if $0 == __FILE__ then
279
- class TestVisitor
280
- include XMLScan::Visitor
281
- def parse_error(msg)
282
- STDERR.printf("%s:%d: %s\n", $s.path, $s.lineno, msg) if $VERBOSE
283
- end
284
- def wellformed_error(msg)
285
- STDERR.printf("%s:%d: WFC: %s\n", $s.path, $s.lineno, msg) if $VERBOSE
286
- end
287
- def warning(msg)
288
- STDERR.printf("%s:%d: warning: %s\n", $s.path,$s.lineno, msg) if $VERBOSE
289
- end
290
- end
291
-
292
- $s = scan = XMLScan::XMLParser.new(TestVisitor.new)
293
- src = ARGF
294
- def src.path; filename; end
295
- t1 = Time.times.utime
296
- scan.parse src
297
- t2 = Time.times.utime
298
- STDERR.printf "%2.3f sec\n", t2 - t1
299
- end