summaryrefslogtreecommitdiffstats
path: root/Tools/scripts
diff options
context:
space:
mode:
authorMarc-André Lemburg <mal@egenix.com>2005-10-21 13:45:17 (GMT)
committerMarc-André Lemburg <mal@egenix.com>2005-10-21 13:45:17 (GMT)
commitc5694c8bf4bf2008b42e0107fb245415df4147fd (patch)
tree8c5ddc2a102cd42329da26805f232f09d3302a2d /Tools/scripts
parent31441302171fe882976bcc05f5ded9645cd690af (diff)
downloadcpython-c5694c8bf4bf2008b42e0107fb245415df4147fd.zip
cpython-c5694c8bf4bf2008b42e0107fb245415df4147fd.tar.gz
cpython-c5694c8bf4bf2008b42e0107fb245415df4147fd.tar.bz2
Moved gencodec.py to the Tools/unicode/ directory.
Added new support for decoding tables. Cleaned up the implementation a bit.
Diffstat (limited to 'Tools/scripts')
-rw-r--r--Tools/scripts/gencodec.py300
1 files changed, 0 insertions, 300 deletions
diff --git a/Tools/scripts/gencodec.py b/Tools/scripts/gencodec.py
deleted file mode 100644
index 75337d6..0000000
--- a/Tools/scripts/gencodec.py
+++ /dev/null
@@ -1,300 +0,0 @@
-""" Unicode Mapping Parser and Codec Generator.
-
-This script parses Unicode mapping files as available from the Unicode
-site (ftp://ftp.unicode.org/Public/MAPPINGS/) and creates Python codec
-modules from them. The codecs use the standard character mapping codec
-to actually apply the mapping.
-
-Synopsis: gencodec.py dir codec_prefix
-
-All files in dir are scanned and those producing non-empty mappings
-will be written to <codec_prefix><mapname>.py with <mapname> being the
-first part of the map's filename ('a' in a.b.c.txt) converted to
-lowercase with hyphens replaced by underscores.
-
-The tool also writes marshalled versions of the mapping tables to the
-same location (with .mapping extension).
-
-Written by Marc-Andre Lemburg (mal@lemburg.com).
-
-(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
-(c) Copyright Guido van Rossum, 2000.
-
-"""#"
-
-import re,os,time,marshal
-
-# Create numeric tables or character based ones ?
-numeric = 1
-
-mapRE = re.compile('((?:0x[0-9a-fA-F]+\+?)+)'
- '\s+'
- '((?:(?:0x[0-9a-fA-Z]+|<[A-Za-z]+>)\+?)*)'
- '\s*'
- '(#.+)?')
-
-def parsecodes(codes,
- len=len, filter=filter,range=range):
-
- """ Converts code combinations to either a single code integer
- or a tuple of integers.
-
- meta-codes (in angular brackets, e.g. <LR> and <RL>) are
- ignored.
-
- Empty codes or illegal ones are returned as None.
-
- """
- if not codes:
- return None
- l = codes.split('+')
- if len(l) == 1:
- return int(l[0],16)
- for i in range(len(l)):
- try:
- l[i] = int(l[i],16)
- except ValueError:
- l[i] = None
- l = filter(lambda x: x is not None, l)
- if len(l) == 1:
- return l[0]
- else:
- return tuple(l)
-
-def readmap(filename):
-
- f = open(filename,'r')
- lines = f.readlines()
- f.close()
- enc2uni = {}
- identity = []
- unmapped = range(256)
- for i in range(256):
- unmapped[i] = i
- for line in lines:
- line = line.strip()
- if not line or line[0] == '#':
- continue
- m = mapRE.match(line)
- if not m:
- #print '* not matched: %s' % repr(line)
- continue
- enc,uni,comment = m.groups()
- enc = parsecodes(enc)
- uni = parsecodes(uni)
- if not comment:
- comment = ''
- else:
- comment = comment[1:]
- if enc < 256:
- unmapped.remove(enc)
- if enc == uni:
- identity.append(enc)
- else:
- enc2uni[enc] = (uni,comment)
- else:
- enc2uni[enc] = (uni,comment)
- # If there are more identity-mapped entries than unmapped entries,
- # it pays to generate an identity dictionary first, and add explicit
- # mappings to None for the rest
- if len(identity)>=len(unmapped):
- for enc in unmapped:
- enc2uni[enc] = (None, "")
- enc2uni['IDENTITY'] = 256
-
- return enc2uni
-
-def hexrepr(t):
-
- if t is None:
- return 'None'
- try:
- len(t)
- except:
- return '0x%04x' % t
- return '(' + ', '.join(map(lambda t: '0x%04x' % t, t)) + ')'
-
-def unicoderepr(t):
-
- if t is None:
- return 'None'
- if numeric:
- return hexrepr(t)
- else:
- try:
- len(t)
- except:
- return repr(unichr(t))
- return repr(''.join(map(unichr, t)))
-
-def keyrepr(t):
-
- if t is None:
- return 'None'
- if numeric:
- return hexrepr(t)
- else:
- try:
- len(t)
- except:
- if t < 256:
- return repr(chr(t))
- else:
- return repr(unichr(t))
- return repr(''.join(map(chr, t)))
-
-def codegen(name,map,comments=1):
-
- """ Returns Python source for the given map.
-
- Comments are included in the source, if comments is true (default).
-
- """
- l = [
- '''\
-""" Python Character Mapping Codec generated from '%s' with gencodec.py.
-
-"""#"
-
-import codecs
-
-### Codec APIs
-
-class Codec(codecs.Codec):
-
- def encode(self,input,errors='strict'):
-
- return codecs.charmap_encode(input,errors,encoding_map)
-
- def decode(self,input,errors='strict'):
-
- return codecs.charmap_decode(input,errors,decoding_map)
-
-class StreamWriter(Codec,codecs.StreamWriter):
- pass
-
-class StreamReader(Codec,codecs.StreamReader):
- pass
-
-### encodings module API
-
-def getregentry():
-
- return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
-
-### Decoding Map
-''' % name,
- ]
-
- if map.has_key("IDENTITY"):
- l.append("decoding_map = codecs.make_identity_dict(range(%d))"
- % map["IDENTITY"])
- l.append("decoding_map.update({")
- splits = 1
- del map["IDENTITY"]
- else:
- l.append("decoding_map = {")
- splits = 0
-
- mappings = map.items()
- mappings.sort()
- append = l.append
- i = 0
- for e,value in mappings:
- try:
- (u,c) = value
- except TypeError:
- u = value
- c = ''
- key = keyrepr(e)
- if c and comments:
- append('\t%s: %s,\t# %s' % (key,unicoderepr(u),c))
- else:
- append('\t%s: %s,' % (key,unicoderepr(u)))
- i += 1
- if i == 4096:
- # Split the definition into parts to that the Python
- # parser doesn't dump core
- if splits == 0:
- append('}')
- else:
- append('})')
- append('decoding_map.update({')
- i = 0
- splits = splits + 1
- if splits == 0:
- append('}')
- else:
- append('})')
- append('''
-### Encoding Map
-
-encoding_map = codecs.make_encoding_map(decoding_map)
-''')
- return '\n'.join(l)
-
-def pymap(name,map,pyfile,comments=1):
-
- code = codegen(name,map,comments)
- f = open(pyfile,'w')
- f.write(code)
- f.close()
-
-def marshalmap(name,map,marshalfile):
-
- d = {}
- for e,(u,c) in map.items():
- d[e] = (u,c)
- f = open(marshalfile,'wb')
- marshal.dump(d,f)
- f.close()
-
-def convertdir(dir,prefix='',comments=1):
-
- mapnames = os.listdir(dir)
- for mapname in mapnames:
- name = os.path.split(mapname)[1]
- name = name.replace('-','_')
- name = name.split('.')[0]
- name = name.lower()
- codefile = name + '.py'
- marshalfile = name + '.mapping'
- print 'converting %s to %s and %s' % (mapname,
- prefix + codefile,
- prefix + marshalfile)
- try:
- map = readmap(os.path.join(dir,mapname))
- if not map:
- print '* map is empty; skipping'
- else:
- pymap(mapname, map, prefix + codefile,comments)
- marshalmap(mapname, map, prefix + marshalfile)
- except ValueError:
- print '* conversion failed'
-
-def rewritepythondir(dir,prefix='',comments=1):
-
- mapnames = os.listdir(dir)
- for mapname in mapnames:
- if not mapname.endswith('.mapping'):
- continue
- codefile = mapname[:-len('.mapping')] + '.py'
- print 'converting %s to %s' % (mapname,
- prefix + codefile)
- try:
- map = marshal.load(open(os.path.join(dir,mapname),
- 'rb'))
- if not map:
- print '* map is empty; skipping'
- else:
- pymap(mapname, map, prefix + codefile,comments)
- except ValueError, why:
- print '* conversion failed: %s' % why
-
-if __name__ == '__main__':
-
- import sys
- if 1:
- apply(convertdir,tuple(sys.argv[1:]))
- else:
- apply(rewritepythondir,tuple(sys.argv[1:]))