* support "string" attributes, starting with s_,

test it in xmlfiletests
* fix: handle unicode in output formatting
This commit is contained in:
Eray Özkural
2005-10-31 15:28:22 +00:00
parent 567efa7fee
commit 9ccd5bbe9a
5 changed files with 50 additions and 15 deletions
+1 -1
View File
@@ -97,7 +97,7 @@ class Path:
return s
class Dependency:
t_Package = [xmlfile.String, xmlfile.mandatory]
s_Package = [xmlfile.String, xmlfile.mandatory]
a_versionFrom = [xmlfile.String, xmlfile.optional]
a_versionTo = [xmlfile.String, xmlfile.optional]
a_releaseFrom = [xmlfile.String, xmlfile.optional]
+43 -10
View File
@@ -37,6 +37,8 @@ from xml.parsers.expat import ExpatError
import locale
import codecs
import types
import formatter
import sys
import gettext
__trans = gettext.translation('pisi', fallback=True)
@@ -94,7 +96,7 @@ class LocalText(object):
if not lang:
lang = 'en'
self.locs[lang] = c
def encode(self, xml, node, errs):
for key in self.locs.iterkeys():
newnode = newNode(node, self.tag)
@@ -123,6 +125,23 @@ class LocalText(object):
else:
errs.append(_("Tag should have at least an English or Turkish version"))
class Writer(formatter.DumbWriter):
"""adds unicode support"""
def __init__(self, file=None, maxcol=78):
formatter.DumbWriter.__init__(self, file, maxcol)
def send_literal_data(self, data):
self.file.write(data.encode("utf-8"))
i = data.rfind('\n')
if i >= 0:
self.col = 0
data = data[i+1:]
data = data.expandtabs()
self.col = self.col + len(data)
self.atbreak = 0
class autoxml(oo.autosuper):
"""High-level automatic XML transformation interface for xmlfile.
The idea is to declare a class for each XML tag. Inside the
@@ -218,18 +237,20 @@ class autoxml(oo.autosuper):
order = dict.keys()
order.sort()
for var in order:
if var.startswith('t_') or var.startswith('a_'):
if var.startswith('t_') or var.startswith('a_') or var.startswith('s_'):
name = var[2:]
if var.startswith('a_'):
x = autoxml.gen_attr_member(cls, name)
elif var.startswith('t_'):
x = autoxml.gen_tag_member(cls, name)
(init, decoder, encoder, checker, formatter) = x
elif var.startswith('s_'):
x = autoxml.gen_str_member(cls, name)
(init, decoder, encoder, checker, format_x) = x
inits.append(init)
decoders.append(decoder)
encoders.append(encoder)
checkers.append(checker)
formatters.append(formatter)
formatters.append(format_x)
# generate top-level helper functions
cls.initializers = inits
@@ -275,8 +296,7 @@ class autoxml(oo.autosuper):
formatter(self, f, errs)
cls.format = format
def print_text(self):
import formatter
w = formatter.DumbWriter() # plain text
w = Writer() # plain text
f = formatter.AbstractFormatter(w)
errs = []
self.format(f, errs)
@@ -307,7 +327,7 @@ class autoxml(oo.autosuper):
spec = getattr(cls, 't_' + tag)
anonfuns = cls.gen_tag(tag, spec)
return cls.gen_named_comp(tag, spec, anonfuns)
def gen_tag(cls, tag, spec):
"""generate readers and writers for the tag"""
tag_type = spec[0]
@@ -330,6 +350,19 @@ class autoxml(oo.autosuper):
raise Error(_('gen_tag: unrecognized tag type %s in spec') %
str(tag_type))
def gen_str_member(cls, token):
"""generate readers and writers for a string member"""
spec = getattr(cls, 's_' + token)
tag_type = spec[0]
assert type(tag_type) == type(type)
def readtext(node, blah):
node.normalize()
return getNodeText(node)
def writetext(xml, node, blah, text):
addText(node, "", text)
anonfuns = cls.gen_anon_basic(token, spec, readtext, writetext)
return cls.gen_named_comp(token, spec, anonfuns)
def gen_named_comp(cls, token, spec, anonfuns):
"""generate a named component tag/attr. a decoration of
anonymous functions that do not bind to variable names"""
@@ -430,14 +463,14 @@ class autoxml(oo.autosuper):
return value
else:
if req == mandatory:
errs.append(_('Mandatory token %s not available') % token)
errs.append(where + _('Mandatory token %s not available') % token)
return None
def encode(xml, node, value, errs):
"""encode given value inside DOM node"""
if value:
#FIXME: unicode() here?
writetext(xml, node, token, str(value))
writetext(xml, node, token, unicode(value))
else:
if req == mandatory:
errs.append(_('Mandatory argument not available'))
@@ -528,7 +561,7 @@ class autoxml(oo.autosuper):
l = []
nodes = getAllNodes(node, path)
#print node, tag + '/' + comp_tag, nodes
if len(nodes) is 0 and req is mandatory:
if len(nodes)==0 and req==mandatory:
errs.append(where + _('Mandatory list empty'))
for ix in range(len(nodes)):
node = nodes[ix]
+1
View File
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<A href="http://www.cs.bilkent.edu.tr/~erayo">
cıvık mantardır bu
<Name>Eray Ozkural</Name>
<Number>868</Number>
<Description>Lazy Tin</Description>
+3 -3
View File
@@ -24,7 +24,7 @@ class SpecFileNewTestCase(testcase.TestCase):
self.spec = specfile.SpecFile()
self.spec.read("tests/popt/pspec.xml")
def testReadSpec(self):
def testFields(self):
self.assertEqual(self.spec.source.name, "popt")
self.assertEqual(self.spec.source.version, "1.7")
@@ -32,7 +32,7 @@ class SpecFileNewTestCase(testcase.TestCase):
self.assertEqual(self.spec.source.release, "3")
self.assertEqual(self.spec.source.archiveSHA1,
"66f3c77b87a160951b180447f4a6dce68ad2f71b")
"66f3c77b87a160951b180447f4a6dce68ad2f71b")
patches = self.spec.source.patches
self.assertEqual(len(patches), 1)
@@ -72,7 +72,7 @@ class SpecFileNewTestCase(testcase.TestCase):
self.fail("Failed to match PartOf in Package")
def testVerify(self):
if self.spec.has_errors():
if self.spec.check() != []:
self.fail("Failed to verify specfile")
def testCopy(self):
+2 -1
View File
@@ -43,11 +43,12 @@ class AutoXmlTestCase(testcase.TestCase):
a_href = [types.StringType, xmlfile.mandatory]
t_Projects = [ [types.StringType], xmlfile.mandatory, 'Project']
t_OtherInfo = [ OtherInfo, xmlfile.optional ]
s_Comment = [ xmlfile.Text, xmlfile.mandatory]
self.A = A
def testDeclaration(self):
self.assertEqual(len(self.A.decoders), 7) # we have seven fields
self.assertEqual(len(self.A.decoders), 8) # how many fields in A?
self.assert_(hasattr(self.A, 'encode'))
def testReadWrite(self):