17db96d56Sopenharmony_ci"""This script generates a Python codec module from a Windows Code Page.
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ciIt uses the function MultiByteToWideChar to generate a decoding table.
47db96d56Sopenharmony_ci"""
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ciimport ctypes
77db96d56Sopenharmony_cifrom ctypes import wintypes
87db96d56Sopenharmony_cifrom gencodec import codegen
97db96d56Sopenharmony_ciimport unicodedata
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_cidef genwinmap(codepage):
127db96d56Sopenharmony_ci    MultiByteToWideChar = ctypes.windll.kernel32.MultiByteToWideChar
137db96d56Sopenharmony_ci    MultiByteToWideChar.argtypes = [wintypes.UINT, wintypes.DWORD,
147db96d56Sopenharmony_ci                                    wintypes.LPCSTR, ctypes.c_int,
157db96d56Sopenharmony_ci                                    wintypes.LPWSTR, ctypes.c_int]
167db96d56Sopenharmony_ci    MultiByteToWideChar.restype = ctypes.c_int
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ci    enc2uni = {}
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_ci    for i in list(range(32)) + [127]:
217db96d56Sopenharmony_ci        enc2uni[i] = (i, 'CONTROL CHARACTER')
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_ci    for i in range(256):
247db96d56Sopenharmony_ci        buf = ctypes.create_unicode_buffer(2)
257db96d56Sopenharmony_ci        ret = MultiByteToWideChar(
267db96d56Sopenharmony_ci            codepage, 0,
277db96d56Sopenharmony_ci            bytes([i]), 1,
287db96d56Sopenharmony_ci            buf, 2)
297db96d56Sopenharmony_ci        assert ret == 1, "invalid code page"
307db96d56Sopenharmony_ci        assert buf[1] == '\x00'
317db96d56Sopenharmony_ci        try:
327db96d56Sopenharmony_ci            name = unicodedata.name(buf[0])
337db96d56Sopenharmony_ci        except ValueError:
347db96d56Sopenharmony_ci            try:
357db96d56Sopenharmony_ci                name = enc2uni[i][1]
367db96d56Sopenharmony_ci            except KeyError:
377db96d56Sopenharmony_ci                name = ''
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ci        enc2uni[i] = (ord(buf[0]), name)
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_ci    return enc2uni
427db96d56Sopenharmony_ci
437db96d56Sopenharmony_cidef genwincodec(codepage):
447db96d56Sopenharmony_ci    import platform
457db96d56Sopenharmony_ci    map = genwinmap(codepage)
467db96d56Sopenharmony_ci    encodingname = 'cp%d' % codepage
477db96d56Sopenharmony_ci    code = codegen("", map, encodingname)
487db96d56Sopenharmony_ci    # Replace first lines with our own docstring
497db96d56Sopenharmony_ci    code = '''\
507db96d56Sopenharmony_ci"""Python Character Mapping Codec %s generated on Windows:
517db96d56Sopenharmony_ci%s with the command:
527db96d56Sopenharmony_ci  python Tools/unicode/genwincodec.py %s
537db96d56Sopenharmony_ci"""#"
547db96d56Sopenharmony_ci''' % (encodingname, ' '.join(platform.win32_ver()), codepage
557db96d56Sopenharmony_ci      ) + code.split('"""#"', 1)[1]
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ci    print(code)
587db96d56Sopenharmony_ci
597db96d56Sopenharmony_ciif __name__ == '__main__':
607db96d56Sopenharmony_ci    import sys
617db96d56Sopenharmony_ci    genwincodec(int(sys.argv[1]))
62