1 # Copyright (C) 2013-2020 Roland Lutz
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 ## \namespace gaf.xmlread
18 ## Reading gEDA schematic/symbol files in XML format.
20 import cStringIO
, xml
.parsers
.expat
21 from gettext
import gettext
as _
28 from gaf
.xmlformat
import *
33 def start_element(self
, name
, attributes
):
36 def end_element(self
, name
):
39 def character_data(self
, data
):
43 def __init__(self
, log
):
46 def start_element(self
, name
, attributes
):
47 self
.log
.error(_("unexpected element \"%s\"") % name
)
50 def end_element(self
, name
):
53 def character_data(self
, data
):
56 self
.log
.error(_("unexpected character data \"%s\"") % s
)
58 class OverbarHandler(NullHandler
):
59 def __init__(self
, log
, text
):
63 def start_element(self
, name
, attributes
):
65 return NullHandler
.start_element(self
, name
, attributes
)
67 self
.text
.append('\n')
68 return NullHandler(self
.log
)
70 def character_data(self
, data
):
71 self
.text
.append(data
.replace('\\', '\\\\'))
73 def end_element(self
, name
):
74 self
.text
.append('\\_')
76 class TextHandler(NullHandler
):
77 def __init__(self
, log
, rev
, attached_to
, data
, attribute_name
):
80 self
.attached_to
= attached_to
83 if attribute_name
is not None:
84 self
.text
.append('%s=' % attribute_name
)
86 def start_element(self
, name
, attributes
):
88 self
.text
.append('\n')
89 return NullHandler(self
.log
)
92 self
.text
.append('\\_')
93 return OverbarHandler(self
.log
, self
.text
)
95 return NullHandler
.start_element(self
, name
, attributes
)
97 def character_data(self
, data
):
98 self
.text
.append(data
.replace('\\', '\\\\'))
100 def end_element(self
, name
):
101 self
.data
.text
= ''.join(self
.text
).encode('utf-8')
102 ob
= self
.rev
.add_object(self
.data
)
103 if self
.attached_to
is not None:
104 self
.rev
.relocate_object(ob
, self
.attached_to
, None)
106 class PathHandler(NullHandler
):
107 def __init__(self
, log
, rev
, data
):
113 def start_element(self
, name
, attributes
):
115 return NullHandler
.start_element(self
, name
, attributes
)
117 self
.fragments
.append('\n')
118 return NullHandler(self
.log
)
120 def character_data(self
, data
):
122 self
.fragments
.append(data
.encode())
123 except UnicodeEncodeError:
124 self
.log
.error(_("non-ASCII character in path data"))
126 def end_element(self
, name
):
127 self
.data
.pathdata
= ''.join(self
.fragments
)
128 self
.rev
.add_object(self
.data
)
132 if angle
!= 0 and angle
!= 90 and angle
!= 180 and angle
!= 270:
136 class ContentHandler(NullHandler
):
137 def __init__(self
, c
, rev
, attached_to
):
141 self
.attached_to
= attached_to
143 def start_element(self
, name
, attributes
):
144 if name
== 'text' or name
== 'attribute':
145 is_attribute
= name
== 'attribute'
146 data
= xorn
.storage
.Text(
147 x
= self
.c
.parse_attribute(
148 attributes
, 'x', None,
149 self
.c
.parse
, 'X coordinate'),
150 y
= self
.c
.parse_attribute(
151 attributes
, 'y', None,
152 self
.c
.parse
, 'Y coordinate'),
153 color
= self
.c
.parse_attribute(
155 5 if is_attribute
else 9,
156 ENUM_COLOR
.index
, 'color'),
157 text_size
= self
.c
.parse_attribute(
158 attributes
, 'size', None,
160 visibility
= self
.c
.parse_attribute(
161 attributes
, 'visible', None if is_attribute
else 1,
162 ENUM_BOOLEAN
.index
, 'text visibility'),
163 show_name_value
= self
.c
.parse_attribute(
164 attributes
, 'show', None if is_attribute
else 0,
165 ENUM_SHOW_NAME_VALUE
.index
, 'show name/value value'),
166 angle
= self
.c
.parse_attribute(
167 attributes
, 'angle', 0,
168 parse_angle
, 'angle'),
169 alignment
= self
.c
.parse_attribute(
170 attributes
, 'alignment', 0,
171 ENUM_ALIGNMENT
.index
, 'alignment'))
174 name
= attributes
.pop('name')
176 self
.c
.log
.error(_("attribute name not specified"))
181 self
.c
.log
, self
.rev
, self
.attached_to
, data
, name
)
184 self
.c
.log
.error(_("non-text element can't be attached"))
190 x
= self
.c
.parse_attribute(
191 attributes
, 'x', None,
192 self
.c
.parse
, 'X coordinate'),
193 y
= self
.c
.parse_attribute(
194 attributes
, 'y', None,
195 self
.c
.parse
, 'Y coordinate'),
196 radius
= self
.c
.parse_attribute(
197 attributes
, 'radius', None,
198 self
.c
.parse
, 'radius'),
199 startangle
= self
.c
.parse_attribute(
200 attributes
, 'startangle', None,
202 sweepangle
= self
.c
.parse_attribute(
203 attributes
, 'sweepangle', None,
205 color
= self
.c
.parse_attribute(
206 attributes
, 'color', 3,
207 ENUM_COLOR
.index
, 'color'),
208 line
= self
.c
.parse_line(attributes
)))
209 return NullHandler(self
.c
.log
)
214 x
= self
.c
.parse_attribute(
215 attributes
, 'x', None,
216 self
.c
.parse
, 'X coordinate'),
217 y
= self
.c
.parse_attribute(
218 attributes
, 'y', None,
219 self
.c
.parse
, 'Y coordinate'),
220 width
= self
.c
.parse_attribute(
221 attributes
, 'width', None,
222 self
.c
.parse
, 'width'),
223 height
= self
.c
.parse_attribute(
224 attributes
, 'height', None,
225 self
.c
.parse
, 'height'),
226 color
= self
.c
.parse_attribute(
227 attributes
, 'color', 3,
228 ENUM_COLOR
.index
, 'color'),
229 line
= self
.c
.parse_line(attributes
),
230 fill
= self
.c
.parse_fill(attributes
)))
231 return NullHandler(self
.c
.log
)
236 x
= self
.c
.parse_attribute(
237 attributes
, 'x', None,
238 self
.c
.parse
, 'X coordinate'),
239 y
= self
.c
.parse_attribute(
240 attributes
, 'y', None,
241 self
.c
.parse
, 'Y coordinate'),
242 radius
= self
.c
.parse_attribute(
243 attributes
, 'radius', None,
244 self
.c
.parse
, 'radius'),
245 color
= self
.c
.parse_attribute(
246 attributes
, 'color', 3,
247 ENUM_COLOR
.index
, 'color'),
248 line
= self
.c
.parse_line(attributes
),
249 fill
= self
.c
.parse_fill(attributes
)))
250 return NullHandler(self
.c
.log
)
252 if name
== 'component':
253 ob
= self
.rev
.add_object(
254 xorn
.storage
.Component(
255 x
= self
.c
.parse_attribute(
256 attributes
, 'x', None,
257 self
.c
.parse
, 'X coordinate'),
258 y
= self
.c
.parse_attribute(
259 attributes
, 'y', None,
260 self
.c
.parse
, 'Y coordinate'),
261 selectable
= self
.c
.parse_attribute(
262 attributes
, 'selectable', True,
263 ENUM_BOOLEAN
.index
, 'selectability'),
264 angle
= self
.c
.parse_attribute(
265 attributes
, 'angle', 0,
266 parse_angle
, 'angle'),
267 mirror
= self
.c
.parse_attribute(
268 attributes
, 'mirror', False,
269 ENUM_BOOLEAN
.index
, 'mirror flag')))
271 symbol_id
= attributes
.pop('symbol')
273 self
.c
.log
.error(_("symbol not specified"))
276 self
.c
.log
.error(_("symbol id can't be empty"))
278 self
.c
.symbol_refs
.append(
279 (self
.rev
, ob
, symbol_id
, self
.c
.log
.lineno
))
281 return ContentHandler(self
.c
, self
.rev
, ob
)
284 x0
= self
.c
.parse_attribute(attributes
, 'x0', None,
285 self
.c
.parse
, 'first X coordinate')
286 y0
= self
.c
.parse_attribute(attributes
, 'y0', None,
287 self
.c
.parse
, 'first Y coordinate')
288 x1
= self
.c
.parse_attribute(attributes
, 'x1', None,
289 self
.c
.parse
, 'second X coordinate')
290 y1
= self
.c
.parse_attribute(attributes
, 'y1', None,
291 self
.c
.parse
, 'second Y coordinate')
294 x
= x0
, y
= y0
, width
= x1
- x0
, height
= y1
- y0
,
295 color
= self
.c
.parse_attribute(
296 attributes
, 'color', 3,
297 ENUM_COLOR
.index
, 'color'),
298 line
= self
.c
.parse_line(attributes
)))
299 return NullHandler(self
.c
.log
)
301 if name
== 'net' or name
== 'pin':
302 is_pin
= name
== 'pin'
303 is_bus
= self
.c
.parse_attribute(attributes
, 'type', False,
304 ENUM_NETTYPE
.index
, 'net/pin type')
307 is_inverted
= self
.c
.parse_attribute(
308 attributes
, 'inverted', False,
309 ENUM_BOOLEAN
.index
, 'invertedness')
317 x0
= self
.c
.parse_attribute(attributes
, 'x0', None,
318 self
.c
.parse
, 'first X coordinate')
319 y0
= self
.c
.parse_attribute(attributes
, 'y0', None,
320 self
.c
.parse
, 'first Y coordinate')
321 x1
= self
.c
.parse_attribute(attributes
, 'x1', None,
322 self
.c
.parse
, 'second X coordinate')
323 y1
= self
.c
.parse_attribute(attributes
, 'y1', None,
324 self
.c
.parse
, 'second Y coordinate')
325 ob
= self
.rev
.add_object(
327 x
= x0
, y
= y0
, width
= x1
- x0
, height
= y1
- y0
,
328 color
= self
.c
.parse_attribute(
329 attributes
, 'color', default_color
,
330 ENUM_COLOR
.index
, 'color'),
333 is_inverted
= is_inverted
))
334 return ContentHandler(self
.c
, self
.rev
, ob
)
337 return PathHandler(self
.c
.log
, self
.rev
, xorn
.storage
.Path(
338 color
= self
.c
.parse_attribute(attributes
, 'color', 3,
339 ENUM_COLOR
.index
, 'color'),
340 line
= self
.c
.parse_line(attributes
),
341 fill
= self
.c
.parse_fill(attributes
)))
343 if name
== 'picture':
344 ob
= self
.rev
.add_object(
345 xorn
.storage
.Picture(
346 x
= self
.c
.parse_attribute(
347 attributes
, 'x', None,
348 self
.c
.parse
, 'X coordinate'),
349 y
= self
.c
.parse_attribute(
350 attributes
, 'y', None,
351 self
.c
.parse
, 'Y coordinate'),
352 width
= self
.c
.parse_attribute(
353 attributes
, 'width', None,
354 self
.c
.parse
, 'width'),
355 height
= self
.c
.parse_attribute(
356 attributes
, 'height', None,
357 self
.c
.parse
, 'height'),
358 angle
= self
.c
.parse_attribute(
359 attributes
, 'angle', 0,
360 parse_angle
, 'angle'),
361 mirror
= self
.c
.parse_attribute(
362 attributes
, 'mirrored', False,
363 ENUM_BOOLEAN
.index
, 'mirror flag'),
366 pixmap_id
= attributes
.pop('pixmap')
368 self
.c
.log
.error(_("pixmap not specified"))
371 self
.c
.log
.error(_("pixmap id can't be empty"))
373 self
.c
.pixmap_refs
.append(
374 (self
.rev
, ob
, pixmap_id
, self
.c
.log
.lineno
))
376 return NullHandler(self
.c
.log
)
378 self
.c
.log
.error(_("unexpected element \"%s\"") % name
)
381 class PixmapHandler(NullHandler
):
382 def __init__(self
, log
, pixmap
, just_verify
):
385 self
.just_verify
= just_verify
386 self
.f
= cStringIO
.StringIO()
388 def character_data(self
, data
):
391 def end_element(self
, name
):
394 data
= xorn
.base64
.decode(self
.f
)
395 except xorn
.base64
.DecodingError
:
396 self
.log
.error(_("base64 decoding error"))
398 if not self
.just_verify
:
399 self
.pixmap
.data
= data
400 elif data
!= self
.pixmap
.data
:
401 self
.log
.warn(_("contents of pixmap file \"%s\" don't match "
402 "embedded data") % self
.pixmap
.filename
)
405 def __init__(self
, log
, load_symbol
, load_pixmap
):
410 self
.symbol_refs
= []
411 self
.pixmap_refs
= []
412 self
.load_symbol
= load_symbol
413 self
.load_pixmap
= load_pixmap
414 self
.use_hybridnum
= False
417 if self
.use_hybridnum
:
418 return xorn
.hybridnum
.parse(x
, 3)
420 return float(xorn
.fixednum
.parse(x
, 3))
422 def parse_attribute(self
, d
, key
, default
, processor
, msg_fragment
):
426 if default
is not None:
428 self
.log
.error(_("%s not specified") % msg_fragment
)
432 except (KeyError, ValueError):
433 self
.log
.error(_("invalid %s \"%s\"") % (msg_fragment
, x
))
435 # guess a well-formed return value from processor function
436 return 0. if processor
== self
.parse
else 0
438 def parse_line(self
, attributes
):
439 line
= xorn
.storage
.LineAttr()
440 line
.width
= self
.parse_attribute(
441 attributes
, 'linewidth', 0, self
.parse
, 'line width')
442 line
.cap_style
= self
.parse_attribute(
443 attributes
, 'capstyle', 0, ENUM_CAPSTYLE
.index
, 'cap style')
444 line
.dash_style
= self
.parse_attribute(
445 attributes
, 'dashstyle', 0, ENUM_DASHSTYLE
.index
, 'dash style')
446 if line
.dash_style
!= 0 and line
.dash_style
!= 1:
447 line
.dash_length
= self
.parse_attribute(
448 attributes
, 'dashlength', None, self
.parse
, 'dash length')
450 line
.dash_length
= 0.
451 if line
.dash_style
!= 0:
452 line
.dash_space
= self
.parse_attribute(
453 attributes
, 'dashspace', None, self
.parse
, 'dash space')
458 def parse_fill(self
, attributes
):
459 fill
= xorn
.storage
.FillAttr()
460 fill
.type = self
.parse_attribute(
461 attributes
, 'filltype', 0, ENUM_FILLTYPE
.index
, 'fill type')
462 if fill
.type == 2 or fill
.type == 3:
463 fill
.width
= self
.parse_attribute(
464 attributes
, 'fillwidth', None, self
.parse
, 'fill width')
465 fill
.angle0
= self
.parse_attribute(
466 attributes
, 'angle0', None, int, 'first fill angle')
467 fill
.pitch0
= self
.parse_attribute(
468 attributes
, 'pitch0', None, self
.parse
, 'first fill pitch')
474 fill
.angle1
= self
.parse_attribute(
475 attributes
, 'angle1', None, int, 'second fill angle')
476 fill
.pitch1
= self
.parse_attribute(
477 attributes
, 'pitch1', None, self
.parse
, 'second fill pitch')
483 class RootElementHandler(NullHandler
):
484 def __init__(self
, c
):
487 self
.rev
= xorn
.storage
.Revision()
488 self
.had_content
= False
490 def start_element(self
, name
, attributes
):
491 if name
== 'content':
493 self
.c
.log
.error(_("duplicate content tag"))
495 self
.had_content
= True
496 return ContentHandler(self
.c
, self
.rev
, None)
500 mode
= attributes
.pop('mode')
502 self
.c
.log
.error(_("symbol mode not specified"))
504 if mode
== 'omitted':
507 elif mode
== 'referenced':
510 elif mode
== 'embedded':
514 self
.c
.log
.error(_("invalid symbol mode \"%s\"") % mode
)
518 name
= attributes
.pop('name')
521 self
.c
.log
.error(_("symbol name not specified"))
525 symbol
= gaf
.ref
.Symbol(name
, None, True)
527 symbol
= self
.c
.load_symbol(name
, read_symbol
)
529 symbol
= gaf
.ref
.Symbol(name
, None, False)
531 assert not symbol
.embedded
533 symbol_id
= attributes
.pop('id')
535 self
.c
.log
.error(_("symbol id not specified"))
538 self
.c
.log
.error(_("symbol id can't be empty"))
540 if symbol_id
in self
.c
.ids
:
541 self
.c
.log
.error(_("duplicate id \"%s\"") % symbol_id
)
543 self
.c
.ids
.add(symbol_id
)
544 self
.c
.symbols
[symbol_id
] = symbol
546 return NullHandler(self
.c
.log
)
548 reh
= RootElementHandler(self
.c
)
550 symbol
.prim_objs
= reh
.rev
555 mode
= attributes
.pop('mode')
557 self
.c
.log
.error(_("pixmap mode not specified"))
559 if mode
== 'omitted':
562 elif mode
== 'referenced':
565 elif mode
== 'embedded':
569 self
.c
.log
.error(_("invalid pixmap mode \"%s\"") % mode
)
573 name
= attributes
.pop('name')
576 self
.c
.log
.error(_("pixmap name not specified"))
580 pixmap
= gaf
.ref
.Pixmap(name
, None, True)
582 pixmap
= self
.c
.load_pixmap(name
, read_pixmap
)
584 pixmap
= gaf
.ref
.Pixmap(name
, None, False)
586 assert not pixmap
.embedded
588 pixmap_id
= attributes
.pop('id')
590 self
.c
.log
.error(_("pixmap id not specified"))
593 self
.c
.log
.error(_("pixmap id can't be empty"))
595 if pixmap_id
in self
.c
.ids
:
596 self
.c
.log
.error(_("duplicate id \"%s\"") % pixmap_id
)
598 self
.c
.ids
.add(pixmap_id
)
599 self
.c
.pixmaps
[pixmap_id
] = pixmap
601 return PixmapHandler(self
.c
.log
, pixmap
, not is_embedded
)
603 return NullHandler(self
.c
.log
)
605 self
.c
.log
.error(_("unexpected element \"%s\"") % name
)
608 def end_element(self
, name
):
609 if not self
.had_content
:
610 self
.c
.log
.error(_("content missing"))
612 def read_file(f
, name
, log
, load_symbol
, load_pixmap
):
613 context
= LoadContext(log
, load_symbol
, load_pixmap
)
614 reh
= RootElementHandler(context
)
616 def start_root_element(name
, attributes
):
617 if name
!= 'symbol' and name
!= 'schematic':
618 log
.error(_("invalid root element \"%s\"") % name
)
621 for feature
in attributes
.pop('file-format-features', '').split(' '):
624 if feature
== 'experimental':
626 elif feature
== 'hybridnum':
627 if context
.use_hybridnum
:
628 log
.error(_("duplicate file format feature"))
629 context
.use_hybridnum
= True
631 log
.error(_("unsupported file format feature \"%s\"")
636 read_xml_file(f
, log
, NAMESPACE
, start_root_element
)
638 for rev
, ob
, symbol_id
, lineno
in context
.symbol_refs
:
639 if symbol_id
not in context
.symbols
:
641 log
.error(_("undefined symbol \"%s\"") % symbol_id
)
643 data
= rev
.get_object_data(ob
)
644 data
.symbol
= context
.symbols
[symbol_id
]
645 rev
.set_object_data(ob
, data
)
647 for rev
, ob
, pixmap_id
, lineno
in context
.pixmap_refs
:
648 if pixmap_id
not in context
.pixmaps
:
650 log
.error(_("undefined pixmap \"%s\"") % pixmap_id
)
652 data
= rev
.get_object_data(ob
)
653 data
.pixmap
= context
.pixmaps
[pixmap_id
]
654 rev
.set_object_data(ob
, data
)
656 return xorn
.proxy
.RevisionProxy(reh
.rev
)
658 def read_xml_file(f
, log
, namespace
, start_root_element
):
661 def strip_namespace(name
, ignore_errors
):
663 pos
= name
.index(NSSEP
)
665 if not ignore_errors
:
666 log
.error(_("element name \"%s\" without namespace") % name
)
669 if name
[:pos
] != namespace
and not ignore_errors
:
670 log
.error(_("invalid namespace \"%s\"") % name
[:pos
])
673 return name
[pos
+ 1:]
675 def StartElementHandler(name
, attributes
):
676 log
.lineno
= p
.CurrentLineNumber
- 1
677 name
= strip_namespace(name
, False)
679 new_handler
= VoidHandler()
681 new_handler
= stack
[-1].start_element(name
, attributes
)
683 new_handler
= start_root_element(name
, attributes
)
684 stack
.append(new_handler
)
686 if attributes
and not isinstance(new_handler
, VoidHandler
):
687 log
.error(_("unexpected attribute(s) %s") % _(", ").join(
688 _("\"%s\"") % attr
for attr
in sorted(attributes
)))
690 def EndElementHandler(name
):
691 log
.lineno
= p
.CurrentLineNumber
- 1
692 name
= strip_namespace(name
, True)
693 stack
.pop().end_element(name
)
695 def CharacterDataHandler(data
):
696 log
.lineno
= p
.CurrentLineNumber
- 1
697 stack
[-1].character_data(data
)
699 def StartDoctypeDeclHandler(doctype_name
, system_id
, public_id
,
700 has_internal_subset
):
701 log
.lineno
= p
.CurrentLineNumber
- 1
702 log
.error(_("unexpected XML document type declaration"))
704 def ElementDeclHandler(name
, model
):
705 log
.lineno
= p
.CurrentLineNumber
- 1
706 log
.error(_("unexpected XML element type declaration"))
708 def AttlistDeclHandler(elname
, attname
, type, default
, required
):
709 log
.lineno
= p
.CurrentLineNumber
- 1
710 log
.error(_("unexpected XML element type attribute declaration"))
712 def ProcessingInstructionHandler(target
, data
):
713 log
.lineno
= p
.CurrentLineNumber
- 1
714 log
.error(_("unexpected XML processing instruction"))
716 def UnparsedEntityDeclHandler(entity_name
, base
, system_id
, public_id
,
718 log
.lineno
= p
.CurrentLineNumber
- 1
719 log
.error(_("unexpected XML unparsed entity declaration"))
721 def EntityDeclHandler(entity_name
, is_parameter_entity
, value
, base
,
722 system_id
, public_id
, notation_name
):
723 log
.lineno
= p
.CurrentLineNumber
- 1
724 log
.error(_("unexpected XML entity declaration"))
726 def NotationDeclHandler(notation_name
, base
, system_id
, public_id
):
727 log
.lineno
= p
.CurrentLineNumber
- 1
728 log
.error(_("unexpected XML notation declaration"))
730 def StartCdataSectionHandler():
731 log
.lineno
= p
.CurrentLineNumber
- 1
732 log
.error(_("unexpected XML CDATA section"))
734 def DefaultHandler(data
):
735 log
.lineno
= p
.CurrentLineNumber
- 1
736 log
.error(_("unexpected characters in XML document"))
738 def NotStandaloneHandler():
739 log
.lineno
= p
.CurrentLineNumber
- 1
740 log
.error(_("XML document hasn't been declared as standalone"))
742 def ExternalEntityRefHandler(context
, base
, systemId
, publicId
):
743 log
.lineno
= p
.CurrentLineNumber
- 1
744 log
.error(_("unexpected reference to external XML entity"))
746 p
= xml
.parsers
.expat
.ParserCreate(namespace_separator
= '!')
748 p
.XmlDeclHandler
= None
749 p
.StartDoctypeDeclHandler
= StartDoctypeDeclHandler
750 p
.EndDoctypeDeclHandler
= None
751 p
.ElementDeclHandler
= ElementDeclHandler
752 p
.AttlistDeclHandler
= AttlistDeclHandler
753 p
.StartElementHandler
= StartElementHandler
754 p
.EndElementHandler
= EndElementHandler
755 p
.ProcessingInstructionHandler
= ProcessingInstructionHandler
756 p
.CharacterDataHandler
= CharacterDataHandler
757 p
.UnparsedEntityDeclHandler
= UnparsedEntityDeclHandler
758 p
.EntityDeclHandler
= EntityDeclHandler
759 p
.NotationDeclHandler
= NotationDeclHandler
760 p
.StartNamespaceDeclHandler
= None
761 p
.EndNamespaceDeclHandler
= None
762 p
.CommentHandler
= None
763 p
.StartCdataSectionHandler
= StartCdataSectionHandler
764 p
.EndCdataSectionHandler
= None
765 p
.DefaultHandler
= DefaultHandler
766 p
.DefaultHandlerExpand
= None
767 p
.NotStandaloneHandler
= NotStandaloneHandler
768 p
.ExternalEntityRefHandler
= ExternalEntityRefHandler
772 except xml
.parsers
.expat
.ExpatError
as e
:
773 log
.lineno
= e
.lineno
- 1
774 log
.error(_("%s") % e
)